文章目录
- 一、监控linux TCP连接状态
- TCP端口的十一种连接状态
- 自定义监控项
- 监控示例
- 二、监控模板
- 监控tcp连接
- 监控nginx
一、监控linux TCP连接状态
TCP,全称Transfer Control Protocol,中文名为传输控制协议,它工作在OSI的传输层,提供面向连接的可靠传输服务,TCP的工作主要是建立连接,然后从应用层程序中接收数据并进行传输。TCP采用虚电路连接方式进行工作,在发送数据前它需要在发送方和接收方建立一个连接,数据在发送出去后,发送方会等待接收方给出一个确认性的应答,否则发送方将认为此数据丢失,并重新发送此数据。
在建立连接的时候,所谓的客户端与服务端是相对应的,即要看是谁主动连接的谁,如果A主动连接B那么A就是客户端而B是服务端,如果返过来B主动连接A,那么B就是客户端而A就成了服务端。
TCP端口的十一种连接状态
状态 | 含义 |
---|---|
CLOSED | 端口默认是关闭状态 |
LISTEN | 服务器程序开始监听一个端口,就是LISTEN状态 |
SYN_RCVD | 三次握手的第二次握手后的端口状态,是收到了客户端发送的SYN_SENT数据包之后的状态,这个状态很短暂,正常在服务器上是很少看到的,除非服务器故意不发送最后一次握手数据包,服务器返回给客户端SYN确认之后就会将在自己的端口置为SYN_RCVD |
SYN_SENT | SYN_SENT状态表示客户端已发送SYN=1的请求连接报文,发送之后客户端就会将自己的端口状态置为SYN_SENT |
ESTABLISHED | 表示已经连接成功,客户端收到服务器的确认报文会回复服务器,然后就将端口置为ESTABLISHED,服务器第三次收到客户端的Ack确认就会将端口置为ESTABLISHED并开始传输数据 |
FIN_WAIT_1 | 出现在主动关闭方,FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,当任意一方想主动关闭连接,向对方发送了FIN=1的断开连接请求报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马 上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到 |
FIN_WAIT_2 | 出现在主动关闭方,当被动方回应FIN_WAIT_1的ACK报文后,则进入到FIN_WAIT_2状态 |
TIME_WAIT | 出现在主动关闭方,表示收到了对方的FIN请求关闭报文,并发送出了ACK报文,就等2*MSL(MaxSegment Lifetime)后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态 |
CLOSING | 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。 |
CLOSE_WAIT | 表示在等待关闭端口,这种状态存在于被动关闭的一方。 |
LAST_ACK | 是被动关闭方在主动关闭一方在发送FIN报文后,最后等待对方的ACK报文,当再次收到ACK报文后,也即可以进入到CLOSED可用状态了。 |
自定义监控项
在客户端配置文件中修改。
客户端设置:
服务端测试:
添加脚本
注意加执行权限。
脚本传参数
监控示例
web界面添加自定义项
添加图形
触发器
二、监控模板
监控tcp连接
准备脚本文件
#!/bin/bash
tcp_conn_status(){TCP_STAT=$1ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}' > /tmp/tcp_conn.txtTCP_NUM=$(grep "$TCP_STAT" /tmp/tcp_conn.txt | cut -d ' ' -f2)if [ -z $TCP_NUM ];thenTCP_NUM=0fiecho $TCP_NUM
}main(){case $1 intcp_status)tcp_conn_status $2;;;esac
}main $1 $2
测试脚本
修改客户端配置文件
服务端测试
在web界面建立模版
设置触发器
特别注意: 键值一定要写对,否则出现不了对应的效果。
监控nginx
安装nginx并配置状态页。
vim /etc/nginx/nginx.conf
location /status {stub_status;}
Active connections: 当前处于活动状态的客户端连接数,包括连接等待空闲连接数。
accepts:统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:统计总值,Nginx自启动后已经处理完成的客户端请求的总数,通常等于accepts,除非有因
worker_connections限制等被拒绝的连接。
requests:统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:当前状态,正在读取客户端请求报文首部的连接的连接数。
Writing:当前状态,正在向客户端发送响应报文过程中的连接数。
Waiting:当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于 active –(reading+writing)。
准备脚本
#!/bin/bash nginx_status_fun(){ #函数内容NGINX_PORT=$1 #端口,函数的第一个参数是脚本的第二个参数,即脚本的第二个参数是段端口号NGINX_COMMAND=$2 #命令,函数的第二个参数是脚本的第三个参数,即脚本的第三个参数是命令nginx_active(){ #获取nginx_active数量,以下相同,这是开启了nginx状态但是只能从本机看到/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Active' | awk '{print $NF}'}nginx_reading(){ #获取nginx_reading状态的数量/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Reading' | awk '{print $2}'}nginx_writing(){/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Writing' | awk '{print $4}'}nginx_waiting(){/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| grep 'Waiting' | awk '{print $6}'}nginx_accepts(){/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $1}'}nginx_handled(){/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $2}'}nginx_requests(){/usr/bin/curl "http://127.0.0.1:"$NGINX_PORT"/status/" 2>/dev/null| awk NR==3 | awk '{print $3}'}case $NGINX_COMMAND inactive)nginx_active;;;reading)nginx_reading;;;writing)nginx_writing;;;waiting)nginx_waiting;;;accepts)nginx_accepts;;;handled)nginx_handled;;;requests)nginx_requests;esac
}main(){ #主函数内容case $1 in #分支结构,用于判断用户的输入而进行响应的操作nginx_status) #当输入nginx_status就调用nginx_status_fun,并传递第二和第三个参数nginx_status_fun $2 $3;;;*) #其他的输入打印帮助信息echo $"Usage: $0 {nginx_status key}"esac #分支结束符
}main $1 $2 $3
主服务器上操作
接下来的操作如上述步骤增加模版。