Published: 03 Jul 2018 › Updated: 03 Jul 2018
记一次服务器大量CLOSE_WAIT的故障处理过程
症状
- CPU正常
- 内存正常
- 网络出现大量CLOSE_WAIT连接状态
- 应用日志文件无异常
其中用到的网络连接统计命令:
netstat -apn|grep 443|awk '{if($2 > 1) print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7}'|sort -k 2
服务器上的应用程序是用Java编写,使用了tomcat,使用命令
jcmd 20165 Thread.print > threads.log
导出线程堆栈情况发现大量的WAITING状态线程,线程总数约200个,大部分线程调用堆栈都包含了httpclient包的调用,查看了对应的Java代码,发现如下写法:
HttpResponse res = httpClient.execute(post);
if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//读取响应内容
resp = EntityUtils.toString(res.getEntity(), "UTF-8");
}
return resp;
推测
如果响应的res状态码不是200,resp对应的输入流是没有正常读取释放的;如果不正常释放,httpclient维护的连接池及单个主机连接数是会被消耗光的,最终出现新的http请求会一直阻塞,进而消耗掉tomcat所有的工作线程(默认工作线程200个左右与thread.log统计一致)。
问题复现
略
解决方案
在if条件后增加else处理,使用方法org.apache.http.util.EntityUtils#consumeQuietly对服务端返回的输入流进行读取消耗。
参考资料
Leave 记一次服务器大量CLOSE_WAIT的故障处理过程 to:
Read more #closewait posts
Best Posts From frank
We have not curated any of qfrank's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.