排查服务器偶发性闪断问题

问题:

上周开始公司托管在IDC机房的一台服务器频繁掉线,导致ssh连接不上,过几分钟又恢复。通过监控查看,没有什么有价值的结果,因为是对公网IP监控的,当时监控是没有数据的,唯一有价值的就是通过监控的No data 时间来看,是不定时触发的,排除了因某些定时任务导致。

过程:

0. 询问机房人员调取监控图

监控排查无果后,果断询问机房人员,调取问题发生的时间段流量监控,发现交换机的入口流量已经超过了100M(百兆交换)导致流量骤增,公网无法访问。 机房那边的的入流量徒增也就是我们服务器这边的出流量,猜测有大量上传操作或者cpu飙升的现象。

1. 排查机器存活

ssh连接不上我们先要确定是 机器确实宕机了 还是 ssh断掉了 还是公网IP无法连接了 ?
问题再次出现时,通过托管在机房的集群环境中其他机器,用内网IP尝试登陆,成功! 机器是存活的,ssh服务也没有挂!所以就是结合前面的结果,问题就在带宽流量打满了,无法连接。

2. 排查机器CPU,内存情况

登录上去以后,top命令 C , 果断找到"罪魁祸首"


image.png

根据PID,找到程序父ID,直接定位是哪个进程引起的

ps -ef|grep id
lQLPDhsMT0YWYM7NAkvNCNuwCHsyCFyYcdUB5NdiSYC-AA_2267_587.png

3.找到“涉事”进程

根据公司业务逻辑java程序都以容器的方式运行,并且可以看到运行信息带有env为prod的字样,用docker ps 找出这个容器

user@ubuntu:/home1/ALG/identification/upload$ docker ps 
CONTAINER ID        IMAGE                                                                                           COMMAND                  CREATED             STATUS              PORTS                    NAMES
ea271034d32b        harbor.hw.xxxx.com:5000/health-cloud-server/health-cloud-ai-manager:883e2fc9-prod      "/bin/sh -c 'java -D…"   11 days ago         Up 11 days          0.0.0.0:8004->9000/tcp   health-cloud-ai-manager-prod_health-cloud-ai-manager_1
8f6accb9cd0c        harbor.hw.xxx.com:5000/health-cloud-server/health-cloud-ai-manager:c9a69dcb-k8s-dev   "/bin/sh -c 'java -D…"   2 weeks ago         Up 2 weeks          0.0.0.0:8001->9000/tcp   health-cloud-ai-manager-dev_health-cloud-ai-manager_1

4.进入容器排查(容器ID-ea271034d32b)

ss命令看soket连接情况

root@ea271034d32b:/# ss
Netid State      Recv-Q Send-Q Local Address:Port         Peer Address:Port     
u_str ESTAB      0      0                  * 694692659               * 0        
u_str ESTAB      0      0                  * 694686601               * 0        
udp   ESTAB      0      0         172.24.0.2:48273             8.8.8.8:domain   
udp   ESTAB      0      0         172.24.0.2:60631        202.106.0.20:domain   
tcp   ESTAB      0      285       172.24.0.2:46840       121.36.25.185:8635     
tcp   SYN-SENT   0      1         172.24.0.2:39208       124.70.70.103:8635     
tcp   SYN-SENT   0      1         172.24.0.2:47412       121.36.25.185:8635     
tcp   CLOSE-WAIT 0      0         172.24.0.2:44428       119.3.214.140:8848     
tcp   SYN-SENT   0      1         172.24.0.2:47386       121.36.25.185:8635     
tcp   ESTAB      0      36844     172.24.0.2:35628      216.118.240.74:http-alt 
tcp   CLOSE-WAIT 1      0         172.24.0.2:48802       119.3.214.140:8848     
tcp   ESTAB      0      33184     172.24.0.2:35634      216.118.240.74:http-alt 
tcp   SYN-SENT   0      1         172.24.0.2:39218       124.70.70.103:8635     
tcp   SYN-SENT   0      1         172.24.0.2:33382       119.3.214.140:8848     
tcp   ESTAB      0      484       172.24.0.2:33378       119.3.214.140:8848     
tcp   ESTAB      0      285       172.24.0.2:38096       124.70.70.103:8635     
tcp   SYN-SENT   0      1         172.24.0.2:52370      216.118.240.74:http-alt 
tcp   CLOSE-WAIT 1      0         172.24.0.2:37550       119.3.214.140:8848     
tcp   ESTAB      0      0         172.24.0.2:43842       119.3.221.159:8501    

结果上看有两处 ESTAB状态时,Send-Q 堆积过多,这肯定是不正常的

tcp   ESTAB      0      36844     172.24.0.2:35628      216.118.240.74:http-alt 

这个客户端IP也比较可疑,来自香港,因为这个服务只是公司内部调用 ,集群机器也没有香港的机器。

5. 询问相关业务人员,是否可以重启

当务之急的解决办法最快清除这些堆积的包与链接,就是重启容器,询问相关业务人员,进行了重启后,再次查看CPU状态已经恢复正常,通过公网IP也可以立刻链接上了,目前需要多观察几天,是否还会复发。

总结:

1.recv-Q 表示网络接收队列

表示收到的数据已经在本地接收缓冲,但是还有多少没有被进程取走,recv()
如果接收队列Recv-Q一直处于阻塞状态,可能是遭受了拒绝服务 denial-of-service 攻击。

2.send-Q 表示网络发送队列

对方没有收到的数据或者说没有Ack的,还是本地缓冲区.
如果发送队列Send-Q不能很快的清零,可能是有应用向外发送数据包过快,或者是对方接收数据包不够快。

从图中可以看到是大量的 send-Q ,可以判定是发送数据给目的地址的时候出现了阻塞的问题,导致了包堆积在本地缓存中,不能成功发出去。那么问题就产生在了客户端, 重启了容器,清掉正发送的队列,再次观察。

3.关于ss 命令和 netstat 命令都是排查网络连接的利器,Recv-Q ,Send-Q的值是如何进行分析的呢?

一. Established状态时:
  • Recv-Q:"OS持有的,尚未交付给应用的 数据的 【字节数】"
  • Send-Q:"已经发送给对端应用,但对端应用尚未ack(确认)的【字节数】。此时,这些数据依然要由OS持有"
二. Listen状态时:
  • Recv-Q:"服务端已经接收到的,但尚未交付给应用的【 tcp连接的数量】"
    (客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端 accept()调用派给应用)
  • Send-Q:listen时,backlog的大小,其值为min(backlog, somaxconn),简单理解为在等待区等待的【连接数】最大值

补充

包括在tomcat调优时会有accept-count ,max-connections 参数

  • max-connections : 允许的最大连接数
  • accept-count : 当超过最大连接数后,将超额的连接放入accept()队列中,等待前面空闲后,os从这里面调用正在等待的连接,如果accept满了,将不会接受任何请求,也就是可能会给客户端返回502,这个accept-count值就是在除了最大连接数,还可以在额外多接受几个连接。

参考:
https://www.cnblogs.com/leezhxing/p/5329786.html
https://blog.csdn.net/yjh314/article/details/51038774

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容