HttpClient引發的執行緒數過多導致應用崩潰
[背景]
應用中執行緒數量 一直在增加,dump執行緒日誌發現大量IdleConnectionEvictor日誌。
原始碼分析:
//evictExpiredConnections 這個配置作用:
//設定一個定時執行緒,定時清理閒置連線,可以將這個定時時間設定為 keep alive timeout 時間的一半以保證超時前回收
//所以在build httpclinet 的時候可以設定evictExpiredConnections()
if (evictExpiredConnections || evictIdleConnections) {
//這裡要看IdleConnectionEvictor原始碼,裡面會建立一個執行緒
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm,
maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit != null ? maxIdleTimeUnit : TimeUnit.SECONDS,
maxIdleTime, maxIdleTimeUnit);
closeablesCopy.add(new Closeable() {
@Override
public void close() throws IOException {
connectionEvictor.shutdown();
try {
connectionEvictor.awaitTermination(1L, TimeUnit.SECONDS);
} catch (final InterruptedException interrupted) {
Thread.currentThread().interrupt();
}
}
});
connectionEvictor.start();//這裡會建立evaictor執行緒
}
所以每建立一個httpclient就會建立一個evictor執行緒,如果不設定連線超時時間和空閒執行緒回收的話這些執行緒會一直存在;
解決方法:
建立httpClient連線池,自定義connectManager
public class HttpClientFactory {
private CloseableHttpClient httpClient;
public void construct(){
RequestConfig config = RequestConfig.custom()
.setSocketTimeout(10000)//請求獲取資料的超時時間(即響應時間),單位毫秒
.setConnectTimeout(10000)//設定連線超時時間,單位毫秒
.setConnectionRequestTimeout(500)//設定從connect Manager(連線池)獲取Connection 超時時間,單位毫秒
.build();
//設定連線存活時間,總的最大連線數和每個路由的最大連線數
PoolingHttpClientConnectionManager poolHttpConnManager = new PoolingHttpClientConnectionManager(60, TimeUnit.SECONDS);
poolHttpConnManager.setMaxTotal(60);
poolHttpConnManager.setDefaultMaxPerRoute(20);
//初始化client
HttpClientBuilder httpBuilder = HttpClients.custom()
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
.setDefaultRequestConfig(config)
.setConnectionManager(poolHttpConnManager)
.evictExpiredConnections()
//MaxIdleTime 必須小於服務端的關閉時間否則有可能出現NoHttpResponse
.evictIdleConnections(5,TimeUnit.SECONDS);//用來關閉閒置連線,它會啟動一個守護執行緒進行清理工作。使用者可以通過builder#evictIdleConnections開啟該元件,並通過builder#setmaxIdleTime設定最大空閒時間。
httpClient=httpBuilder.build();
}
public void destroy() throws Exception{
if(null != this.httpClient){
this.httpClient.close();
}
}
}
相關文章
- 執行緒崩潰為什麼不會導致 JVM 崩潰執行緒JVM
- 記錄一個LifeCycle 多執行緒使用導致的崩潰執行緒
- 案例解析:執行緒池使用不當導致的系統崩潰執行緒
- Node出錯導致執行崩潰的解決方案
- 總結:iOS中多執行緒的經典崩潰iOS執行緒
- 多執行緒應用執行緒
- 當主執行緒崩潰而其它執行緒繼續執行時發生什麼(2)(轉)執行緒
- 當主執行緒崩潰而其它執行緒繼續執行時發生什麼(1)(轉)執行緒
- iOS開發-stringByEvaluatingJavaScriptFromString導致崩潰iOSJavaScript
- WebMagic多執行緒導致註解失效問題Web執行緒
- MySQL連線數過多導致服務無法正常執行MySql
- C# 多執行緒引數傳遞C#執行緒
- 深入理解Java多執行緒與併發框(第⑪篇)——執行緒池引數Java執行緒
- java中如何給多執行緒中子執行緒傳遞引數?Java執行緒
- ObjC 多執行緒簡析(一)-多執行緒簡述和執行緒鎖的基本應用OBJ執行緒
- iOS載入單張圖片導致崩潰的分析iOS
- 解決ajax請求引數過多導致引數被截斷的問題
- Java多執行緒/併發12、多執行緒訪問static變數Java執行緒變數
- 不要升級!不要升級!MacOS 14.4 引發Java 應用崩潰MacJava應用崩潰
- OS開發基礎——多執行緒的簡單應用執行緒
- pymysql 非執行緒安全導致的故障.MySql執行緒
- python中多執行緒和多程序的應用Python執行緒
- Java多執行緒/併發14、保持執行緒間的資料獨立:ConcurrentHashMap應用Java執行緒HashMap
- A站大流量導致服務崩潰異常分析
- 模態對話方塊可能導致程式崩潰
- 私有網路介面丟失導致例項崩潰
- hp-unix 殭屍程式導致系統崩潰
- 多塊硬碟離線導致raid6崩潰的資料恢復案例硬碟AI資料恢復
- 多執行緒與併發-----條件阻塞Condition的應用執行緒
- 多執行緒應用初探(一)----(概念,安全)執行緒
- iOS中多執行緒之GCD應用iOS執行緒GC
- Java 多執行緒應用 之 ArrayBlockingQueueJava執行緒BloC
- 關於jboss最大執行緒數滿導致服務停止執行緒
- Java多執行緒/併發05、synchronized應用例項:執行緒間操作共享資料Java執行緒synchronized
- Java多執行緒/併發13、保持執行緒間的資料獨立: Collections.synchronizedMap應用Java執行緒synchronized
- PyQt應用程式中的多執行緒:使用Qt還是Python執行緒?QT執行緒Python
- 通過原始碼理解 Java 執行緒池的核心引數原始碼Java執行緒
- 多執行緒中自定義執行緒池與shiro導致的許可權錯亂問題解決執行緒