标签:
前几天写一个小脚本,爬几个页面,自己写着玩的,但是中间出现一些情况,做下备忘
在我已经设置了SocketTimeout 和 ConnectTimeout 还会出现请求一个地址的时候就卡死在那里的情况,也不知道什么原因,也没有报错,就那么卡着了
后来我跟到了httpclient的源码里这个类MainClientExec 的 方法
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
config.getConnectionRequestTimeout()
然后在RequestConfig里增加上了这个配置,以为就完事了,结果倒是不卡在某一个地址了,直接报错
Timeout waiting for connection
这个错误上网找了找,百度谷歌都试了,大概的意思是开了很多求情但是没有正常关闭
http://www.blogjava.net/wangxinsh55/archive/2012/07/16/383210.html
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}‘
发现CLOSE_WAIT的数量始终在400以上,一直没降过。
我又看了下自己的代码,没有出现获取inputstream没有关闭的情况的啊,因为我创建文件也好,获取网页源码也好,都是使用的EntityUtils提供的方法,这个工具类都会在finally里关闭inputstream
再次检查代码,主要查找没有关闭 CloseableHttpResponse 的地方加上response.close()终于发现问题。
我在一个地方使用了CloseableHttpResponse response = httpClient.execute(post);
但是在下面我有一个if判断,我把response的close放在了判断里,而没有进入判定为真的请求,response 就无法关闭了,导致了连接池被占满无法释放
知道了问题解决就轻松加愉快了,也告诫了我,以后response 一定要关闭
httpclient 4.3.3 Timeout waiting for connection
标签:
原文地址:http://my.oschina.net/u/943305/blog/487953