2014-09-17 7 views
16

Hier ist, wie ich es verwenden -Apache PoolingHttpClientConnectionManager wirft illegale staatliche Ausnahme

private static final PoolingHttpClientConnectionManager connPool; 

static { 

     connPool = new PoolingHttpClientConnectionManager(); 
     // Increase max total connection to 200 
     connPool.setMaxTotal(200);//configurable through app.properties 
     // Increase default max connection per route to 50 
     connPool.setDefaultMaxPerRoute(20);//configurable through app.properties 

} 

CloseableHttpClient httpClient = HttpClients.custom() 
       .setConnectionManager(connPool) .build(); 

ALso habe ich ein schließlich setzte Block um http GET -

finally { 
      try { 
       httpClient.close(); 
      } catch (IOException e) { 
       LOGGER.error(e.getMessage()); 
      } 
     } 

Hier ist mein Stacktrace -

java.lang.IllegalStateException: Connection pool shut down 
    at org.apache.http.util.Asserts.check(Asserts.java:34) 
    at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:169) 
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:217) 
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:157) 
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194) 
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85) 
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108) 
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106) 
    at com.A.B.C.CustomHttpClient.doGETAndValidate(CustomHttpClient.java:44) 
    at com.A.B.C.SiteMonitorTask.monitorAndUpdateEndPoints(SiteMonitorTask.java:48) 
    at com.A.B.C.SiteMonitorTask.run(SiteMonitorTask.java:37) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 

Ich verwende Quartz, um einen Job der Überwachung von HTTP-Endpunkten zu planen. Hier ist mein Verbindungspool con

Figuration
totalMaxHttpConn=200 
maxHttpConnPerRoute=20 

Maven Abhängigkeit .. Artefakt Version

httpclient 4.3.1 
httpcore 4.3.1 

EDIT - Nun das Problem entkam durch nicht CloseableHttpClient in der schließlich Schließung blockiert .. Kann mir jemand sagen, warum ist es so zu verhalten? Warum wird der Verbindungspool heruntergefahren, wenn ich einen Client schließe?

Ist closeablehttpclient über einen Griff an den Pool ist eher als eine einzelne Anschl

+0

Und wo ist der Code, wo Sie auf den Pool zugreifen? Meine Wette ist, dass der Pool von jemandem geschlossen wird, wenn Sie darauf zugreifen. – prabugp

+0

Reicht der obige Code aus? – abipc

+0

War auf der Suche nach einem geeigneten Doc-Link, um das zu erklären. Sie sollten die Verbindung freigeben und nicht schließen. Sie schließen nicht wirklich einen Client. IOW, ein Client ist die tatsächliche Verbindung, die Sie zu Ihrer HTTP-URL erstellen. – prabugp

Antwort

9

Dieses Verhalten aufgrund eines Fehlers in HC 4.3 ist. Es wurde bereits in HC 4.4a1 behoben. Ab 4.4 CloseableHttpClient#close sollte den Verbindungspool nur dann automatisch herunterfahren, wenn der Kunde ausschließlich dem Kunden gehört

+0

Kennen Sie die Bug-ID? – abipc

+0

Kein Ticket wurde für den Defekt ausgelöst, aber ich kann Ihnen die Revisionsnummer geben, wenn Sie möchten – oleg

+0

Ab sofort, behob das Problem durch Entfernen von httpClient.close() .. Teste nicht die rev Nummer von oleg zur Verfügung gestellt .. – abipc

25

In Version 4.4 wurde die Methode setConnectionManagerShared zu HttpClientBuilder hinzugefügt. Wenn Sie es auf "True" setzen, wird der Client den Verbindungsmanager nicht schließen.

HttpClients.custom() 
      .setConnectionManager(Util.getConnectionManager()) // shared connection manager 
      .setConnectionManagerShared(true)