TCP,全称Transfer Control Protocol,中文名为传输控制协议,它工作在OSI的传输层,提供面向连接的可靠传输服务,TCP的工作主要是建立连接,然后从应用层程序中接收数据并进行传输。TCP采用虚电路连接方式进行工作,在发送数据前它需要在发送方和接收方建立一个连接,数据在发送出去后,发送方会等待接收方给出一个确认性的应答,否则发送方将认为此数据丢失,并重新发送此数据。
在建立连接的时候,所谓的客户端与服务端是相对应的,即要看是谁主动连接的谁,如果A主动连接B那么A就是客户端而B是服务端,如果返过来B主动连接A,那么B就是客户端而A就成了服务端。
TCP端口的十一种连接状态
CLOSED:端口默认是关闭状态。
LISTEN: 服务器程序开始监听一个端口,就是LISTEN状态。
SYN_SENT:SYN_SENT状态表示客户端已发送SYN=1的请求连接报文,发送之后客户端就会将自己的端口状态置为SYN_SENT。
SYN_RCVD:三次握手的第二次握手后的端口状态,是收到了客户端发送的SYN_SENT数据包之后的状态,这个状态很短暂,正常在服务器上是很少看到的,除非服务器故意不发送最后一次握手数据包,服务器返回给客户端SYN确认之后就会将在自己的端口置为SYN_RCVD。
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(Max Segment 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可用状态了。
监控TCP连接数脚本
生产中建议在/etc/zabbix/zabbix_agentd.conf.d目录里放子配置文件 xxx.conf
针对不同的配置去写子配置文件,可视化效果好
如果是脚本,建议建一个专门放置脚本的文件夹,比如 /etc/zabbix/zabbix_agentd.conf.d/scripts/
创建放脚本的目录
mkdir -p /etc/zabbix/zabbix_agentd.conf.d/scripts/
创建脚本/etc/zabbix/zabbix_agentd.conf.d/scripts/tcp_conn_plugin.sh
#!/bin/bash
#Author:xiao qin wa
tcp_conn_status(){
TCP_STAT=$1
ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}' > /tmp/tcp_conn.txt
TCP_NUM=$(grep "$TCP_STAT" /tmp/tcp_conn.txt | cut -d ' ' -f2)
if [ -z $TCP_NUM ];then
TCP_NUM=0
fi
echo $TCP_NUM
}
main(){
case $1 in
tcp_status)
tcp_conn_status $2;
;;
esac
}
main $1 $2
给脚本执行权限,然后在agent上测试运行是否能获取到数据
cd /etc/zabbix/zabbix_agentd.conf.d/scripts/
chmod +x ./tcp_conn_plugin.sh
./tcp_conn_plugin.sh tcp_status ESTAB
编辑/etc/zabbix/zabbix_agentd.conf
Include=/etc/zabbix/zabbix_agentd.conf.d/*.conf
创建/etc/zabbix/zabbix_agentd.conf.d/all.conf
添加自定义监控项,这里的KEY必须和模板配置的监控项的KEY一致
UserParameter=linux_status[*],/etc/zabbix/zabbix_agentd.d/scripts/tcp_conn_plugin.sh "$1" "$2"
重启服务
systemctl restart zabbix-agent
在zabbix server用zabbix_get命令测试能否取到数据
zabbix_get -s "这里换成agent的IP" -k "linux_status[tcp_status,ESTAB]"
如果提示权限不足/tmp/tcp_conn.txt: Permission denied
需要在zabbix agent上授权
chown zabbix.zabbix /tmp/tcp_conn.txt
成功取到数据以后就可以去制作模板了
模板制作
在web端制作好模板,添加监控项、触发器、图形,最后关联主机就可以开始监控了。
注意模板里的key必须和agent配置文件里的key对应,不然会报错。
时间间隔一般设置五分钟。
我制作的模板下载地址
https://drive.google.com/file/d/1_EfImC6qFkfc6WF5kMVMExnOsatKLxLG/view?usp=sharing
关联后等待一段时间就能看到数据了