问题描述
1、监控系统发现电商网站主页及其他页面间歇性的无法访问;
2、查看安全防护和网络流量、应用系统负载均衡正常;
3、系统重启后,能暂时解决,但持续一段时间后间歇性问题再次出现。
此时问题已经影响到整个网站的正常业务,我的那个心惊的呀,最主要报警系统没有任何报警,服务运行一切正常,瞬时背上的汗已经出来了,但还是要静心,来仔细寻找蛛丝马迹,来一步一步找问题。
问题初步判断:
1、检查dev和网卡设备层,是否有error和drop
cat /proc/net/dev 和ifconfig,分析在硬件和系统层,未发现异常
2、观察socket overflow和socket dropped(如果应用处理全连接队列(accept queue)过慢socket overflow,影响半连接队列(syn queue)溢出socket dropped)急增加。
3、检查sysctl内核参数:backlog,somaxconn,file-max和应用程序的backlog
ss -lnt查询,send-q 会取上述参数的最小值,发现当时队列已经超过已经超过网站80端口和443端口默认值
4、检查selinux和NetworkManger是否启用,禁用状态
5、检查timestap,reuse启用,内核recycle是否启用,如果过NAT,禁用recycle
6、抓包判断请求进来后应用处理的情况,是否收到SYN未响应情况
深入分析问题:
正常TCP建连接三次握手过程:
第一步:客户端发送syn到服务器端发起握手;
第二步:服务端收到syn后回复syn+ack给客户端
第三步:客户端收到syn+ack后,回复服务端一个ack表示收到了服务端的syn+ack。
从描述的情况来看,TCP建连接的时候全连接队列(accept队列)满了,尤其是描述中症状为了证明这个原因。反复看了几次之后发现这个overflowed一直在增加,那么可以明确的是server上全连接队列一定溢出了。
接着查看溢出后,os怎么处理:
# cat /proc/sys/net/ipv4/tcp_abort_on_overflow
tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client发过来的ack(在server端认为连接还没建立起来)
为了证明客户端应用代码的异常跟全连接队列满有关系,我先把tcp_abort_on_overflow修改为1,1表示