java - org.apache.http.ConnectionClosedException : Connection closed - PoolingNHttpClientConnectionManager

标签 java https connection-pooling apache-httpcomponents apache-httpasyncclient

我们在生产中经常遇到以下错误。原因是,服务器关闭了连接,而客户端正在尝试使用半关闭的陈旧连接。我们有驱逐策略,每 80 分钟定期运行一次,它将检查过期和空闲的连接并关闭它们。我们仍然收到这个错误。我们计划将驱逐线程间隔缩短至 40 分钟。有没有其他解决方案可以阻止此错误?

我们正在使用 PoolingNHttpClientConnectionManager。空闲期超时时间为 60 秒。httpasyncclient 版本为 4.1.1。

org.apache.http.ConnectionClosedException: Connection closed
        at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.endOfInput(HttpAsyncRequestExecutor.java:341)
        at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:263)
        at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:81)
        at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39)
        at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:123)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:164)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:339)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:317)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:278)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:590)
        at java.lang.Thread.run(Thread.java:748)

最佳答案

有两个选项:

  1. 在连接管理器构建时为所有连接定义有限的 TTL(总生存时间)限制
  2. 使用自定义 ConnectionKeepAliveStrategy 实现来强制持久连接的相对过期时间。

以下是 HttpAsyncClient 配置示例,该配置强制执行 2 分钟的总生存时间限制和 30 秒的相对过期时间

请注意,这可能无法完全消除问题,因为客户端和服务器这两个端点可能会在没有事先握手的情况下随时关闭连接。

ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(IOReactorConfig.custom()
        .build());
PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(
        ioReactor,
        ManagedNHttpClientConnectionFactory.INSTANCE,
        RegistryBuilder.<SchemeIOSessionStrategy>create()
                .register("http", NoopIOSessionStrategy.INSTANCE)
                .register("https", SSLIOSessionStrategy.getSystemDefaultStrategy())
                .build(),
        DefaultSchemePortResolver.INSTANCE,
        SystemDefaultDnsResolver.INSTANCE,
        2,
        TimeUnit.MINUTES);
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setConnectionManager(cm)
        .setConnectionManagerShared(false)
        .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
            @Override
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                long keepAliveDuration = super.getKeepAliveDuration(response, context);
                if (keepAliveDuration > 30000) {
                    keepAliveDuration = 30000;
                }
                return keepAliveDuration;
            }
        })
        .build();

关于java - org.apache.http.ConnectionClosedException : Connection closed - PoolingNHttpClientConnectionManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59215518/

相关文章:

java - Paypal SetExpressCheckout Soap

objective-c - NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9802) https 连接错误

ruby-on-rails - Rails 的 form_tag 助手不使用 HTTPS 提交?

django - django + PyMongo 池化的最佳实践?

c# - 为什么将我们的 .NET/SQL Server 网站移动到新主机会导致超过连接池大小?

java - 带有Gradle和mongodb的JHipster错误版本2.23.0

Java:如何中止从 System.in 读取的线程

javascript - jQuery 下拉菜单不适用于 HTTPS 而适用于 HTTP

mysql - 很难根据允许的最大连接数正确设置 RAILS_MAX_THREADS

java - Blackberry 中的独立邮件 API