相信大家在做系统调优的时候希望能加快TIME_WAIT状态的回收,通常将net.ipv4.tcp_tw_recycle选项开启,请注意这里有个坑:
tcp three-way handshake
3way.png
故障现象
有天突然从公司访问自建的gitlab访问很不稳定,经常性的连接超时,但是从其他网络去访问缺很正常,第一反应应该是公司的网络不稳定,经过仔细排查公司网络并无故障且访问其他网络均正常,折腾了好久,最后想着来抓包分析分析:
当超时的情况出现时,服务器端其实是已经接送到TCP三次握手的SYN包,但不回应ACK给客户端,导致客户端一直处于等待状态,导致服务器不相应的原因一般来说都是资源耗尽,但是我们这台服务器的负载并不是很高,又是一通乱查,到了下班还无果。。。下班后发现使用的人少了,访问突然就正常了,这么一想肯定是TCP建立连接的时候出现了问题,发现是开启了net.ipv4.tcp_tw_recycle,在关闭后就正常了;
原因分析
当开启了tcp_tw_recycle选项后,当连接进入TIME_WAIT状态后,会记录对应远端主机最后到达分节的时间戳。如果同样的主机有新的分节到达,且时间戳小于之前记录的时间戳,即视为无效,相应的数据包会被丢弃;
我们的gitlab的使用程度还是比较重的,这也导致了在上班时间内一个公网IP(经过NAT)大量地去反问服务器,不同客户端的时间可能不一致,所以就会出现时间戳错乱的现象,于是后面的数据包就被丢弃了,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK,还可以通过下面命令来确认数据包不断被丢弃的现象;
总结
很多时候我们在做系统调优的情况时,都是直接在网上看一堆的内核参数,然后直接使用,却没有仔细研究过,很多时候,坑只有是自己拆过后才能记住,像这次这个net.ipv4.tcp_tw_recycle故障网上很多分享,看过和自己碰到过还真不一样,好记性不如烂笔头,慢慢记录,慢慢积累,坑应该会越来越少的;
- 查看主机TCP连接数
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'











网友评论