版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
HttpClient 連接池拋出大量ConnectionPoolTimeoutExceptionTimeoutwaitingforconnection 異常排查今天解決了一個 HttpClient 的異常,汗啊,一個HttpClient 使用稍有不慎都會是毀滅級別的啊。這里有之前因為route配置不當(dāng)導(dǎo)致服務(wù)器異常的一個處理: 里面的HttpConnectionManager 實現(xiàn)就是我在這里使用的實現(xiàn)。問題表現(xiàn):tomcat后臺日志發(fā)現(xiàn)大量異常 [plain]viewoutException:Timeoutwaitingforconnection時間一長tomcat就無法繼續(xù)處理其他請求,從假死變成真死了。linux運(yùn)行:[plain]viewplaincopyprint?netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}' 發(fā)現(xiàn)CLOSE_WAIT 的數(shù)量始終在 400以上,一直沒降過。問題分析:一開始我對我的 HttpClient 使用過程深信不疑,我不認(rèn)為異常是來自這里。所以我開始從 TCP的連接狀態(tài)入手,猜測可能導(dǎo)致異常的原因。 以前經(jīng)常遇到 TIME_WAIT數(shù)過大導(dǎo)致的服務(wù)器異常, 很容易解決,修改下sysctl就ok了。但是這次是 CLOSE_WAIT,是完全不同的概念了。關(guān)于TIME_WAIT 和CLOSE_WAIT 的區(qū)別和異常處理我會單獨起一篇文章詳細(xì)說說我的理解。簡單來說CLOSE_WAIT 數(shù)目過大是由于被動關(guān)閉連接處理不當(dāng)導(dǎo)致的。我說一個場景,服務(wù)器A會去請求服務(wù)器B上面的apache獲取文件資源,正常情況下,如果請求成功,那么在抓取完資源后服務(wù)器 A會主動發(fā)出關(guān)閉連接的請求,這個時候就是主動關(guān)閉連接,連接狀態(tài)我們可以看到是TIME_WAIT。如果一旦發(fā)生異常呢?假設(shè)請求的資源服務(wù)器B上并不存在,那么這個時候就會由服務(wù)器 B發(fā)出關(guān)閉連接的請求,服務(wù)器A就是被動的關(guān)閉了連接, 如果服務(wù)器 A被動關(guān)閉連接之后自己并沒有釋放連接,那就會造成CLOSE_WAIT 的狀態(tài)了。所以很明顯,問題還是處在程序里頭。先看看我的HttpConnectionManager實現(xiàn):[java]viewplaincopyprint?publicclassHttpConnectionManager{privatestaticHttpParamshttpParams;privatestaticClientConnectionManagerconnectionManager;/***最大連接數(shù)*/publicfinalstaticintMAX_TOTAL_CONNECTIONS=800;/***獲取連接的最大等待時間*/publicfinalstaticintWAIT_TIMEOUT=60000;/***每個路由最大連接數(shù)*/publicfinalstaticintMAX_ROUTE_CONNECTIONS=400; /**連接超時時間 */ publicfinalstaticintCONNECT_TIMEOUT=10000; /**時時間 */ publicfinalstaticintREAD_TIMEOUT=10000; static{ httpParams=newBasicHttpParams();
**讀取超設(shè)置最大連接數(shù)ConnManagerParams.setMaxTotalConnections(httpParams,MAX_TOTAL_CONNECTIONS); //設(shè)置獲取連接的最大等待時間ConnManagerParams.setTimeout(httpParams,WAIT_TIMEOUT); //設(shè)置每個路由最大連接數(shù)ConnPerRouteBeanconnPerRoute=newConnPerRouteBean(MAX_ROUTE_CONNECTIONS);ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute); //設(shè)置連接超時時間HttpConnectionParams.setConnectionTimeout(httpParams,CONNECT_TIMEOUT); //設(shè)置讀取超時時間HttpConnectionParams.setSoTimeout(httpParams,READ_TIMEOUT);
SchemeRegistryregistry=newSchemeRegistry();
registry.register(newScheme("http",PlainSocketFactory.getSocketFactory(),80)); registry.register(newScheme("https",SSLSocketFactory.getSocketFactory(),443));connectionManager=newThreadSafeClientConnManager(httpParams,registry);
}
publicstaticHttpClientgetHttpClient(){
returnnewDefaultHttpClient(connectionManager,httpParams);
}
}看到?jīng)]
MAX_ROUTE_CONNECTIONS
正好是
400,跟CLOSE_WAIT 非常接近啊,難道是巧合?繼續(xù)往下看。然后看看調(diào)用它的代碼是什么樣的: [java]viewplaincopyprint?publicstaticStringreadNet(StringurlPath){StringBuffersb=newStringBuffer();HttpClientclient=null;InputStreamin=null;InputStreamReaderisr=null;try{client=HttpConnectionManager.getHttpClient();HttpGetget=newHttpGet();get.setURI(newURI(urlPath));HttpResponseresponse=client.execute(get);if(response.getStatusLine().getStatusCode()!=200){ returnnull; }HttpEntityentity=response.getEntity();if(entity!=null){in=entity.getContent();.....}returnsb.toString();}catch(Exceptione){e.printStackTrace();returnnull;}finally{if(isr!=null){try{isr.close();}catch(IOExceptione){e.printStackTrace();}}if(in!=null){try{<spanstyle="color:#ff0000;">in.close();</span>}catch(IOExceptione){e.printStackTrace();}}}}很簡單,就是個遠(yuǎn)程讀取中文頁面的方法。值得注意的是這一段代碼是后來某某同學(xué)加上去的,看上去沒啥問題,是用于非200狀態(tài)的異常處理: [java]viewplaincopyprint?if(response.getStatusLine().getStatusCode()!=200){ returnnull; }代碼本身沒有問題,但是問題是放錯了位置。如果這么寫的話就沒問題:[java]viewplaincopyprint?client=HttpConnectionManager.getHttpClient();HttpGetget=newHttpGet();get.setURI(newURI(urlPath));HttpResponseresponse=client.execute(get);HttpEntityentity=response.getEntity();if(entity!=null){ in=entity.getContent(); .......... }if(response.getStatusLine().getStatusCode()!=200){ returnnull; }returnsb.toString(); 看出毛病了吧。在這篇入門HttpClient4.X升級入門+http連接池使用)里頭我提到了HttpClient4使用我們常用的InputStream.close()來確認(rèn)連接關(guān)閉,前面那種寫法 InputStreamin 根本就不會被賦值,意味著一旦出現(xiàn)非 200的連接,這個連接將永遠(yuǎn)僵死在連接池里頭,太恐怖了。。。所以我們看到 CLOST_WAIT 數(shù)目為400,因為對一個路由的連接已經(jīng)完全被僵死連接占滿了。 。。其實上面那段代碼還有一個沒處理好的地方,異常處理不夠嚴(yán)謹(jǐn),所以最后我把代碼改成了這樣:[java]viewplaincopyprint?publicstaticStringreadNet(StringurlPath){StringBuffersb=newStringBuffer();HttpClientclient=null;InputStreamin=null;InputStreamReaderisr=null;HttpGetget=newHttpGet();try{clientHttpConnectionManager.getHttpClient();get.setURI(newURI(urlPath));HttpResponseresponse=client.execute(get);if(response.getStatusLine().getStatusCode()!=200){ get.abort(); returnnull; } HttpEntityentity=response.getEntity();if(entity!=null){ in=entity.getContent(); ......} returnsb.toString(); } catch(Exceptione) { get.abort();e.printStackTrace(); returnnull;finally { if(isr!=null){ try{ isr.close(); }
}catch(IOExceptione){e.printS
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2025學(xué)年徐州市邳州市三上數(shù)學(xué)期末調(diào)研模擬試題含解析
- 2024-2025學(xué)年新疆維吾爾巴音郭楞蒙古自治州尉犁縣數(shù)學(xué)三年級第一學(xué)期期末達(dá)標(biāo)測試試題含解析
- 2025年氫能源項目申請報告模板
- 2025年水處理阻垢分散劑系列項目規(guī)劃申請報告模范
- 2021教師辭職報告(15篇)
- 《烏鴉喝水》教案范文匯編5篇
- 高中語文教研工作計劃錦集5篇
- 員工年終總結(jié)體會10篇
- 有關(guān)高中語文周記四篇
- 少年宮活動計劃集錦9篇
- 2024年度上海市嘉定區(qū)工業(yè)廠房買賣合同2篇
- 2023-2024學(xué)年廣東省廣州市海珠區(qū)九年級(上)期末化學(xué)試卷(含答案)
- 青年應(yīng)有鴻鵠志當(dāng)騎駿馬踏平川課件高三上學(xué)期勵志主題班會
- 河北省唐山市2021-2022學(xué)年高三上學(xué)期語文期末試卷
- 華電甘肅能源有限公司華電系統(tǒng)內(nèi)外招聘真題
- 新疆大學(xué)答辯模板課件模板
- 數(shù)值分析智慧樹知到期末考試答案2024年
- (正式版)HGT 22820-2024 化工安全儀表系統(tǒng)工程設(shè)計規(guī)范
- 2024年浙江省新華書店集團(tuán)招聘筆試參考題庫附帶答案詳解
- 跨文化溝通心理學(xué)智慧樹知到期末考試答案2024年
- 《中華民族共同體概論》考試復(fù)習(xí)題庫(含答案)
評論
0/150
提交評論