前几天写一个小脚本,爬几个页面,本身写着玩的,可是中间出现一些状况,作下备忘html
在我已经设置了SocketTimeout 和 ConnectTimeout 还会出现请求一个地址的时候就卡死在那里的状况,也不知道什么缘由,也没有报错,就那么卡着了java
后来我跟到了httpclient的源码里这个类MainClientExec 的 方法 app
public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException
try { final int timeout = config.getConnectionRequestTimeout(); managedConn = connRequest.get(timeout > 0 ? timeout : 0, TimeUnit.MILLISECONDS); } catch(final InterruptedException interrupted) { Thread.currentThread().interrupt(); throw new RequestAbortedException("Request aborted", interrupted); } catch(final ExecutionException ex) { Throwable cause = ex.getCause(); if (cause == null) { cause = ex; } throw new RequestAbortedException("Request execution failed", cause); }
这里获取了一个timeout tcp
config.getConnectionRequestTimeout()
而后在RequestConfig里增长上了这个配置,觉得就完事了,结果却是不卡在某一个地址了,直接报错工具
Timeout waiting for connectionpost
这个错误上网找了找,百度谷歌都试了,大概的意思是开了不少求情可是没有正常关闭spa
http://www.blogjava.net/wangxinsh55/archive/2012/07/16/383210.html .net
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' code
发现CLOSE_WAIT的数量始终在400以上,一直没降过。htm
我又看了下本身的代码,没有出现获取inputstream没有关闭的状况的啊,由于我建立文件也好,获取网页源码也好,都是使用的EntityUtils提供的方法,这个工具类都会在finally里关闭inputstream
再次检查代码,主要查找没有关闭 CloseableHttpResponse 的地方加上response.close()终于发现问题。
我在一个地方使用了CloseableHttpResponse response = httpClient.execute(post);
可是在下面我有一个if判断,我把response的close放在了判断里,而没有进入断定为真的请求,response 就没法关闭了,致使了链接池被占满没法释放
知道了问题解决就轻松加愉快了,也告诫了我,之后response 必定要关闭