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 多執行緒使用導致的崩潰執行緒
- 案例解析:執行緒池使用不當導致的系統崩潰執行緒
- 總結:iOS中多執行緒的經典崩潰iOS執行緒
- iOS開發-stringByEvaluatingJavaScriptFromString導致崩潰iOSJavaScript
- 多執行緒應用執行緒
- WebMagic多執行緒導致註解失效問題Web執行緒
- java中如何給多執行緒中子執行緒傳遞引數?Java執行緒
- ObjC 多執行緒簡析(一)-多執行緒簡述和執行緒鎖的基本應用OBJ執行緒
- 深入理解Java多執行緒與併發框(第⑪篇)——執行緒池引數Java執行緒
- MySQL連線數過多導致服務無法正常執行MySql
- 不要升級!不要升級!MacOS 14.4 引發Java 應用崩潰MacJava應用崩潰
- python中多執行緒和多程序的應用Python執行緒
- 解決ajax請求引數過多導致引數被截斷的問題
- pymysql 非執行緒安全導致的故障.MySql執行緒
- OS開發基礎——多執行緒的簡單應用執行緒
- 多執行緒與併發-----條件阻塞Condition的應用執行緒
- 多塊硬碟離線導致raid6崩潰的資料恢復案例硬碟AI資料恢復
- PyQt應用程式中的多執行緒:使用Qt還是Python執行緒?QT執行緒Python
- 多執行緒應用初探(一)----(概念,安全)執行緒
- A站大流量導致服務崩潰異常分析
- 誤升級GLIBC導致系統崩潰之後
- 模態對話方塊可能導致程式崩潰
- 通過原始碼理解 Java 執行緒池的核心引數原始碼Java執行緒
- Json序列化與反序列化導致多執行緒執行速度和單執行緒執行速度一致問題JSON執行緒
- 多執行緒中自定義執行緒池與shiro導致的許可權錯亂問題解決執行緒
- iOS應用崩潰了,如何透過崩潰手機連線電腦查詢日誌方法iOS應用崩潰
- 用多執行緒,實現併發,TCP執行緒TCP
- 儲存崩潰導致資料丟失如何處理
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- pytest(13)-多執行緒、多程式執行用例執行緒
- 多執行緒併發篇——如何停止執行緒執行緒
- 多執行緒與高併發(一)多執行緒入門執行緒
- Standby_file_management引數導致日誌無法應用
- 多執行緒和多執行緒同步執行緒
- C# 帶引數帶互鎖多執行緒呼叫方法C#執行緒
- 多執行緒之應知應會執行緒
- 執行緒以及多執行緒,多程式的選擇執行緒