我们在生产中经常遇到以下错误。原因是,服务器关闭了连接,而客户端正在尝试使用半关闭的陈旧连接。我们有驱逐策略,每 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)
最佳答案
有两个选项:
- 在连接管理器构建时为所有连接定义有限的 TTL(总生存时间)限制
- 使用自定义
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/