执行 REST 请求的执行器服务



我正在尝试使用并发发送未定义数量的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)

似乎主线程关闭得太快,导致创建的可运行对象引发这些异常。

有没有办法强制执行器服务等待可运行对象完成(在关闭 HttpClient 之前)?我应该使用其他策略吗?

提前谢谢。

问候。

尝试更改此行代码;

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

自;

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

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

我不是 100% 确定为什么此修复程序有效,因为围绕此的文档非常糟糕。为了得到这个解决方案,我对我正在测试的内容进行了大量的试验和错误。不过,从我所能收集到的信息来看,此修复程序之所以有效,是因为它随后在后台使用共享连接池,这意味着连接保持开放状态以供使用。

最新更新