ExecutorService执行REST请求

时间:2017-01-19 14:35:44

标签: java httpclient executorservice

我正在尝试使用concurrecy发送未定义数量的HTTP Rest请求。这是基本的代码框架:

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(maxConn);
connManager.setDefaultMaxPerRoute(maxConn);
    CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).build();

ExecutorService es = Executors.newFixedThreadPool(maxConn);

for (...){
   es.execute(new RequestThread(httpclient, ...other data for creating a request...));
}

es.shutdown();
es.awaitTermination(timeout, TimeUnit.SECONDS);
//Tested timeout = 30

httpclient.close();

RequestThread的基本代码是:

    public class RequestThread implements Runnable {

public RequestThread(CloseableHttpClient httpclient, ..other neccesay data..){
   ...
}

    @Override
    public void run() {
	try {
	    processRequest(httpclient, ...);
                // In this method, each CloseableHttpResponse is consumed and closed properly.
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

它多次抛出此异常:

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:184)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
    at com.ericsson.http.DMHttpCommunicationManager.executeRequestMethod(DMHttpCommunicationManager.java:109)
    at com.ericsson.http.RequestThread.processRequest(RequestThread.java:39)
    at com.ericsson.http.RequestThread.run(RequestThread.java:25)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

似乎主线程太快关闭并导致创建的runnables抛出这些异常。

有没有办法强制ExecutorService等待runnable完成(在关闭HttpClient之前)?我应该使用其他策略吗?

提前致谢。

问候。

1 个答案:

答案 0 :(得分:1)

尝试更改此行代码;

CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).build();

要;

CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).setConnectionManagerShared(true).build();

当我遇到这个帖子时,我遇到了类似的错误,这似乎解决了我的问题。我知道这是一个老问题,但为其他人添加想法以供将来参考。

我不是100%肯定为什么这个修复工作,因为围绕这个的文档非常糟糕。我正在测试以获得此解决方案,这是一次试验和错误。从我可以收集的内容来看,此修复程序可以正常工作,因为它在后台使用共享连接池,这意味着连接保持打开状态以供使用。