其中用到的网络连接统计命令:
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对服务端返回的输入流进行读取消耗。