很多同学在做监控告警、异常侦测时专注于软件本身的数据,而忽略了TCP连接状态的监控,其实TCP连接真实的反应了服务器和服务本身的队列情况,是最灵敏的服务阴晴表。

    现在的服务之间都是通过网络进行通信,而很多服务通信是基于TCP的方式,包括大家 熟悉的HTTP、FTP等,在工作中,服务启动后监听指定端口,然后按照特定的7层协议通过此端口接收处理任务,4层使用TCP 通信传输,举个例子,比如说常见的php-fpm,启动后监听TCP9000端口,七层使用fastcgi协议接收nginx分发过来的任务, 当9000端口ESTABLISHED状态的数量突然增大时,说明php-fpm一定是服务抖动或者堵了,造成了任务在TCP层面的积压,难以很快的消化处理掉,查看对应的php-fpm活跃进程数也会激增或者打满,当长时间降不下去,就要去检查服务了,原因可能是请求量激增,亦或是后端依赖资源或接口超时导致,而这些通过TCP就可以很灵敏的监控出来,还有个好处,php-fpm去获取活跃连接数是比较重的,当业务堵时,还增大了php-fpm的压力,很可能超时取不到数据,但获取端口的连接数就不一样了,不存在取不到的情况。所以,当一个监听端口的服务不知道如何监控时,不妨先从TCP的各个指标入手。

    另外从整体上看,tcp状态也是服务器健康状态的一个反应,当受到某些网络攻击时,tcp连接也能第一时间反应出来,比如说syn攻击,当服务器上有大量SYN-RECEIVED半连接状态时,十有八九是有问题了,正常情况下,三次握手肉眼抓不到时延的。例如我目前监控的一个tcp连接状况如下:
    TCP连接监控 - 图1
    这个是uwsgi的一个监控,从曲线上看,ESTAB连接数是不稳定的,间接说明服务是有抖动的,同步去查询访问量,如果访问量没有突然增加,那么说明服务本身可能不稳定,因为请求会突然积压,结合uwsgi是进程堵塞的方式处理任务,就需要去查一堵的下原因了。
    找了一张对一次TCP连接完美诠释的图如下,从三次握手到数据传输到四次挥手:
    TCP连接监控 - 图2
    对于所有的状态说明如下:
    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:没有任何连接状态