前幾天寫一個小腳本,爬幾個頁面,本身寫着玩的,可是中間出現一些狀況,作下備忘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 必定要關閉