CLOSE_WAIT 过多导致 Jetty 服务器假死
近段时间线上环境出现了 CLOSE_WAIT 过多,Jetty 服务器无响应(假死情况)。关于 CLOSE_WAIT 的说明,网上的解答有很多,有兴趣的可以浏览查看参考资料列出来的链接。
一开始,记录到的信息只有网络方面的数据,包括并发数和网络参数,如下:
(项目的并发数) 321
TIME_WAIT 533
CLOSE_WAIT 970
FIN_WAIT1 25
FIN_WAIT2 46
ESTABLISHED 592
SYN_RECV 9
CLOSING 1
LAST_ACK 5
其中第一个数据的记录命令为:
netstat -an | grep 'ESTABLISHED' | grep -i '9001' | wc -l
(其中 9001 是 web 服务器监听端口)
第二个数据的记录命令为:netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
当然这部分的数据,也可以用 Zabbix 监控,图形界面,更方便查看和分析。
根据网上的资料,大部分都是调整 Linux 网络参数,主要是以下三个:(可以参考http://lvxuehu.iteye.com/blog/452487)
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_keepalive_intvl=3
修改这些参数,只能治标不能治本。
后面想到的是通过 java 的工具,查看出现问题时的堆栈信息。结果发现线上的服务器并没有 jstack 命令,排查发现原来的运维装的是 jre,而不是 jdk(汗),完美的错过了一次记录出现问题信息的记录。
在安装之后,最后通过命令:jstack -l 9430 记录当时的堆栈信息,最终定位到问题出在一个影响全局的大锁上。所有的处理都出现等待情况,阻塞在这个地方。
总结:出现线上故障时,尽可能多的记录当时的信息,有利于后面定位排查问题,解决的方法才能处理到点上。CLOSE_WAIT 问题根源还是在服务器上,需要从自己的代码入手。
参考资料:
https://huoding.com/2016/01/19/488
https://www.cnblogs.com/kevin-wu/archive/2006/11/27/574369.html
版权声明: 本文为 InfoQ 作者【风翱】的原创文章。
原文链接:【http://xie.infoq.cn/article/b914b473969ed404587d31296】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论