那些年我们踩到过的坑(二):3.1 版 MultiThreadedHttpConnectionManager 未releaseConnection导致应用服务器宕机...
昨天短信服務(wù)又宕機(jī)了,jstack打出線程信息發(fā)現(xiàn) 所有線程池的線程都在wait,棧信息如下:
at java.lang.Object.wait(Native Method)
- waiting on [0x000000070754fb60] (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.doGetConnection(MultiThreadedHttpConnectionManager.java:518)
- locked [0x000000070754fb60] (a org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$ConnectionPool)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.getConnectionWithTimeout(MultiThreadedHttpConnectionManager.java:416)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:153)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at com.dhf.sms.util.HttpUtil.getHtml(HttpUtil.java:75)
at com.dhf.sms.core.impl.MDSmsserviceImpl.send(MDSmsserviceImpl.java:165)
at com.dhf.sms.core.SmsTask.run(SmsTask.java:156)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at com.kuaidadi.framework.thread.bean.TaxiFutureTask.run(TaxiFutureTask.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
?
發(fā)現(xiàn)所有線程都卡在MultiThreadedHttpConnectionManager 的doGetConnection方法:
? hostPool.waitingThreads.addLast(waitingThread);connectionPool.waitingThreads.addLast(waitingThread);connectionPool.wait(timeToWait);//卡在這查看代碼和google,發(fā)現(xiàn)應(yīng)該是connection連接未釋放的問題的。如果不調(diào)用getMethod.getResponseBodyAsString(),就不會(huì)釋放connection。并且我們沒有指定maxConnectionsPerHost,默認(rèn)為2,所以當(dāng)以下代碼在第16行拋出exception后連接不會(huì)被釋放掉,一旦發(fā)生兩次,那么僅有的2個(gè)connection都被占用,新進(jìn)來的線程就卡住了。
1 public static String getHtml(String url,String charSet,Integer channelId) throws IOException, SmsHttpStatusException { 2 StaticLogInfo staticLogInfo = new StaticLogInfo(); 3 staticLogInfo.setCmd("Channel "+channelId+"("+getHost(url)+")"); 4 GetMethod getMethod = null; 5 try { 6 if (StringUtils.isBlank(charSet)) { 7 charSet = SmsConstant.DEFAULT_CHARSET; 8 } 9 10 getMethod = new GetMethod(url); 11 int statusCode = httpClient.executeMethod(getMethod); 12 if (statusCode != HttpStatus.SC_OK 13 && statusCode != HttpStatus.SC_MOVED_PERMANENTLY 14 && statusCode != HttpStatus.SC_MOVED_TEMPORARILY) { 15 log.error("statusCode:" + statusCode + " url請求失敗========>" + url); 16 throw new SmsHttpStatusException("請求失敗"); 17 } 18 19 String responseBody = new String(getMethod.getResponseBodyAsString().getBytes(charSet),SmsConstant.DEFAULT_CHARSET); 20 return responseBody; 21 } catch (IOException e) { 22 staticLogInfo.setResultCode("1"); 23 throw e; 24 } catch (SmsHttpStatusException e) { 25 staticLogInfo.setResultCode("1"); 26 throw e; 27 } finally { 28 29 reqLogger.info(staticLogInfo); 30 } 31 } 32?
?
解決辦法是在finally里釋放connection:
finally {if(getMethod!=null){getMethod.releaseConnection();}reqLogger.info(staticLogInfo);}并且增加最大連接數(shù):
httpConnectionManagerParams.setMaxTotalConnections(100);httpConnectionManagerParams.setDefaultMaxConnectionsPerHost(20);?
參考:http://blog.csdn.net/xiaojianpitt/article/details/7818971
轉(zhuǎn)載于:https://www.cnblogs.com/longzhaoyu/p/4563513.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的那些年我们踩到过的坑(二):3.1 版 MultiThreadedHttpConnectionManager 未releaseConnection导致应用服务器宕机...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Genymotion的使用 -- A F
- 下一篇: Hadoop项目实战-用户行为分析之应用