2014-11-21 18 views
7

khi tôi sử dụng httpclient 4.3 như sauHttpClient 4.3 chặn kết nối hồ bơi

static { 
    try { 
     SSLContextBuilder builder = new SSLContextBuilder(); 
     builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); 
     SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); 

     CookieSpecProvider easySpecProvider = new CookieSpecProvider() { 

      public CookieSpec create(HttpContext context) { 
       return new BrowserCompatSpec() { 
        @Override 
        public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException { 
         // Oh, I am easy 
        } 
       }; 
      } 

     }; 
     Registry<CookieSpecProvider> r = RegistryBuilder.<CookieSpecProvider> create() 
       .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) 
       .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory()) 
       .register("easy", easySpecProvider).build(); 
     RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) 
       .setSocketTimeout(10000).setConnectTimeout(10000).setCookieSpec("easy").setRedirectsEnabled(false) 
       .build(); 

     PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); 
     cm.setMaxTotal(100); 
     cm.setDefaultMaxPerRoute(10); 

     client = HttpClients.custom().setConnectionManager(cm).setDefaultCookieSpecRegistry(r) 
       .setSSLSocketFactory(sslsf).setDefaultRequestConfig(requestConfig).build(); 
    } catch (Exception e) { 
     logger.error("http client init fail!", e); 
    } 
} 

public static String execute(HttpRequest httpRequest) { 
    CloseableHttpResponse response = null; 
    HttpGet httpGet = null; 
    HttpEntity httpEntity = null; 

    try { 
     httpGet = new HttpGet(httpRequest.getUrl()); 

     httpGet.setHeader("Connection", "close"); 
     if (httpRequest.isUseGzip()) { 
      httpGet.addHeader("Accept-Encoding", "gzip,deflate,sdch"); 
     } 
     if (!StringUtils.isEmpty(httpRequest.getContentType())) { 
      httpRequest.setContentType(httpRequest.getContentType()); 
     } 
     httpGet.addHeader("User-Agent", 
       "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); 

     response = client.execute(httpGet); 
     httpEntity = response.getEntity(); 

     byte[] bytes = null; 
     try { 
      bytes = EntityUtils.toByteArray(httpEntity); 
     } catch (Exception e) { 
      return null; 
     } 

     if (response.getStatusLine().getStatusCode() != 200) { 
      logger.warn("error! StatusCode: " + response.getStatusLine().getStatusCode() + ", url: " 
        + httpRequest.getUrl()); 
      return null; 
     } 

     @SuppressWarnings("deprecation") 
     String charset = EntityUtils.getContentCharSet(httpEntity); 
     if (StringUtils.isEmpty(charset)) { 
      Matcher match = charsetPatterm.matcher(new String(bytes)); 

      if (match.find()) { 
       charset = match.group(1); 
      } 
     } 
     if (!StringUtils.isEmpty(charset)) { 
      String strUtf8 = new String(new String(bytes, charset).getBytes(), GlobalConfig.ENCODING); 

      return StringEscapeUtils.unescapeHtml4(strUtf8); 
     } 
    } catch (Exception e) { 
     logger.error("error! url [" + httpRequest.getUrl() + "]", e); 
    } finally { 
     try { 
      if (httpEntity != null) { 
       EntityUtils.consume(httpEntity); 
      } 
      if (response != null) { 
       response.close(); 
      } 
      if (httpGet != null) { 
       httpGet.abort(); 
      } 
     } catch (Exception e) { 
      // ignore 
     } 
    } 

    return null; 
} 

chủ đề sẽ chặn .. jstack hiển thị như thế này. Tôi chỉ sử dụng nó để thu thập thông tin một số trang web. Điều này xảy ra khi mã trạng thái là 404.
Using Java Apache PoolingClientConnectionManager leaks the Memory,How to solve it? vấn đề của tôi tương tự như vậy.

"pool-1-thread-10" prio=10 tid=0x00007f7168003000 nid=0x3e4d waiting on condition [0x00007f717c398000] 
    java.lang.Thread.State: WAITING (parking) 
     at sun.misc.Unsafe.park(Native Method) 
     - parking to wait for <0x00000000e69d7350> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) 
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) 
     at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:133) 
     at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:282) 
     at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64) 
     at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:177) 
     at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:170) 
     at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:102) 
     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.jav 
a:244) 
     at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:231) 
     at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:173) 
     at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195) 
     at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86) 
     at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) 
     at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) 
     at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
     at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) 

cách giải quyết?

+0

Vui lòng gắn thẻ này là Java. –

+0

Có phải vấn đề mà chuỗi đang chờ và bạn không muốn nó chờ? –

+2

Hãy thử tiêu thụ nội dung thực thể cho các phản hồi 40x, vì luồng không bị đóng, kết nối không được giải phóng, do đó, tiêu thụ hoàn toàn (luồng) được yêu cầu – Ironluca

Trả lời

6

Tôi gặp vấn đề tương tự và đây là phản hồi đầu tiên. Tôi đã sử dụng bình luận của Ironluca để giải quyết vấn đề của tôi nhưng cảm thấy điều này cần một câu trả lời đầy đủ.

quick start guide có một ví dụ gọn gàng về cách thiết lập và sử dụng HttpClient cơ bản.

// In order to ensure correct deallocation of system resources 
// the user MUST call CloseableHttpResponse#close() from a finally clause. 
// Please note that if response content is not fully consumed the underlying 
// connection cannot be safely re-used and will be shut down and discarded 
// by the connection manager. 
try { 
    System.out.println(response1.getStatusLine()); 
    HttpEntity entity1 = response1.getEntity(); 
    // do something useful with the response body 
    // and ensure it is fully consumed 
    EntityUtils.consume(entity1); 
} finally { 
    response1.close(); 
} 

Nhìn lại câu hỏi của bạn có vẻ như bạn đã đóng và sử dụng mã.
Bạn cũng có một hồ bơi kết nối tùy chỉnh. Nó giống như mặc định nhưng tôi đoán bạn đã cấu hình nó theo cách khác.

1

Tôi đã gặp lỗi tương tự. Có vẻ như chúng ta cần tiêu thụ HttpEntity trước khi trở về. Trong trường hợp của bạn, tôi thấy rằng bạn không làm điều này khi bạn gặp phải 200 câu trả lời. Bạn vừa trở về null. Bạn có thể cần phải tiêu thụ điều này trước khi trở về. Ngoài ra, tôi khuyên bạn nên sử dụng HttpClientUtils.closeQuietly (response); đó là trình bao bọc xung quanh EntityUtils.consume

Các vấn đề liên quan