TCP的鏈接狀態對於咱們web服務器來講是相當重要的,尤爲是併發量ESTAB;或者是syn_recv值,假如這個值比較大的話咱們能夠認爲是否是受到了攻擊,或是是time_wait值比較高的話,咱們要考慮看咱們內核是否須要調優,過高的time_wait值的話會佔用太多端口,要是端口少的話後果不堪設想html
TCP狀態介紹
man netstat查看TCP的各類狀態信息描述:
LISTEN
偵聽來自遠方TCP端口的鏈接請求;SYN-SENT
在發送鏈接請求後等待匹配的鏈接請求;SYN-RECEIVED
在收到和發送一個鏈接請求後等待對鏈接請求的確認;ESTABLISHED
表明一個打開的鏈接,數據能夠傳送給用戶;FIN-WAIT-1
等待遠程TCP的鏈接中斷請求,或先前的鏈接中斷請求的確認;FIN-WAIT-2
從遠程TCP等待鏈接中斷請求;CLOSE-WAIT
等待從本地用戶發來的鏈接中斷請求;CLOSING
等待遠程TCP對鏈接中斷的確認;LAST-ACK
等待原來發向遠程TCP的鏈接中斷請求的確認;TIME-WAIT
等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認;CLOSED
沒有任何鏈接狀態;
監控原理
root@Node1 ~]# /bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' //經過netstat獲取相關值 LISTEN 10 ESTABLISHED 1 TIME_WAIT 178
監控腳本編寫
- 編寫腳本,放於
/etc/zabbix/zabbix_agentd.d/
目錄下
[root@Node1 zabbix_agentd.d]# cat tcp_status.sh #!/bin/bash #This script is used to get tcp and udp connetion status #tcp status metric=$1 tmp_file=/tmp/tcp_status.txt /bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' > $tmp_file case $metric in closed) output=$(awk '/CLOSED/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; listen) output=$(awk '/LISTEN/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; synrecv) output=$(awk '/SYN_RECV/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; synsent) output=$(awk '/SYN_SENT/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; established) output=$(awk '/ESTABLISHED/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; timewait) output=$(awk '/TIME_WAIT/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; closing) output=$(awk '/CLOSING/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; closewait) output=$(awk '/CLOSE_WAIT/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; lastack) output=$(awk '/LAST_ACK/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; finwait1) output=$(awk '/FIN_WAIT1/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; finwait2) output=$(awk '/FIN_WAIT2/{print $2}' $tmp_file) if [ "$output" == "" ];then echo 0 else echo $output fi ;; *) echo -e "\e[033mUsage: sh $0 [closed|closing|closewait|synrecv|synsent|finwait1|finwait2|listen|established|lastack|timewait]\e[0m" esac
- 賦予腳本執行權限
[root@Node1 ~]# chmod a+x /etc/zabbix/zabbix_agentd.d/tcp_status.sh //賦予執行權限 [root@Node1 ~]# ll /etc/zabbix/zabbix_agentd.d/tcp_status.sh -rwxr-xr-x 1 root root 2502 Jan 18 09:48 /etc/zabbix/zabbix_agentd.d/tcp_status.sh [root@Node1 ~]#
- 添加zabbix配置文件,放於 /etc/zabbix/zabbix_agentd.d/目錄下(agent的配置文件 /etc/zabbix/zabbix_agentd.conf 中定義了其餘key的包含目錄)建立配置文件tcp_status.conf
[root@Node1 ~]# cat /etc/zabbix/zabbix_agentd.d/tcp_status.conf UserParameter=tcp.status[*],/etc/zabbix/zabbix_agentd.d/tcp_status.sh "$1" //腳本路徑
- 確保配置Agent配置文件開啓自定義參數
UnsafeUserParameters=1
[root@Node1 ~]# grep -n "^[a-Z]" /etc/zabbix/zabbix_agentd.conf 13:PidFile=/var/run/zabbix/zabbix_agentd.pid 32:LogFile=/var/log/zabbix/zabbix_agentd.log 43:LogFileSize=0 57:DebugLevel=3 97:Server=172.17.21.208 138:ServerActive=172.17.21.208 149:Hostname=Node1.contoso.com 267:Include=/etc/zabbix/zabbix_agentd.d/*.conf 286:UnsafeUserParameters=1 //1表明容許,0表明關閉
- 重啓zabbix-agent服務
[root@Node1 ~]# systemctl restart zabbix-agent.service
備註 :由於腳本是把tcp的一些信息存放在/tmp/下,爲了zabbix能夠讀取到咱們設置zabbix能夠讀的權限,確保屬主與屬組都爲zabbix便可git
[root@Node1 ~]# chown zabbix.zabbix /tmp/tcp_status.txt //改變屬主與屬主 [root@Node1 ~]# ll /tmp/tcp_status.txt -rw-rw-r-- 1 zabbix zabbix 38 Jan 18 11:32 /tmp/tcp_status.txt
- 在zabbix servere服務器上測試,是否能正常獲取數據
[root@Node3 ~]# zabbix_get -s 172.17.21.206 -p 10050 -k "tcp.status[listen]" [root@Node3 ~]# zabbix_get -s 172.17.21.206 -p 10050 -k "tcp.status[timewait]" [root@Node3 ~]# zabbix_get -s 172.17.21.206 -p 10050 -k "tcp.status[established]" [root@Node3 ~]#
後記:發現經過netstat監控服務器的tcp等鏈接數效率比較低,netstat統計佔用大量cpu帶來服務器額外的壓力,經過ss命令會更加合適,詳情請看:這篇文章web