解決httpclient因為保持永久長連接造成連接吊死的問題
阿新 • • 發佈:2017-09-29
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));View Code6 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();
解決httpclient因為保持永久長連接造成連接吊死的問題