1. 程式人生 > >解決httpclient因為保持永久長連接造成連接吊死的問題

解決httpclient因為保持永久長連接造成連接吊死的問題

elong cli 連接池 分享 時間 val response 對比 logs

httpclient使用了連接池,如果沒有設置keep-alive策略,PoolingHttpClientConnectionManager會默認使用永久連接。

最近在調用京東api時,發現一個請求開始是可以獲取到數據的,但隔了兩分鐘後再請求就會出現read timeout異常。對比請求成功和請求失敗的日誌後發現,請求成功的有以下日誌“Connection: keep-alive”,“Connection can be kept alive indefinitely”;但請求失敗的卻打印“Shutdown connection”,“Connection discarded”。每次失敗後再請求都會成功。因此推測中應該是對方服務器端禁止長連接,當連接到達一定時間會就會斷開。後來上網找到keep-alive策略的代碼,添加策略後,問題解決。

技術分享
 1 ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() {
 2 
 3             @Override
 4             public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
 5                 HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
6 while (it.hasNext()) { 7 HeaderElement he = it.nextElement(); 8 String param = he.getName(); 9 String value = he.getValue(); 10 if (value != null && param.equalsIgnoreCase("timeout")) {
11 try { 12 return Long.parseLong(value) * 1000; 13 } 14 catch (NumberFormatException ignore) { 15 16 } 17 } 18 } 19 HttpHost target = (HttpHost) context.getAttribute(HttpClientContext.HTTP_TARGET_HOST); 20 if ("bizapi.jd.com ".equalsIgnoreCase(target.getHostName())) { 21 return 60 * 1000; 22 } 23 else { 24 return 300 * 1000; 25 } 26 27 CloseableHttpClient httpClient = httpClientBuilder.setConnectionManager(pollingConnectionManager) 28 .setKeepAliveStrategy(keepAliveStrategy).setDefaultRequestConfig(defaultRequestConfig).build();
View Code

解決httpclient因為保持永久長連接造成連接吊死的問題