org.apache.http.ConnectionClosedException: 连接已关闭 - PoolingNHttpClientConnectionManager
org.apache.http.ConnectionClosedException: Connection closed - PoolingNHttpClientConnectionManager
我们在生产中经常遇到以下错误。原因是,服务器关闭了连接,而客户端正在尝试使用半关闭的陈旧连接。我们有每 80 分钟定期运行一次的驱逐策略,它将检查过期和空闲连接并关闭它们。我们仍然收到此错误。我们计划将驱逐线程间隔减少到 40 分钟。是否有任何其他解决方案可用于阻止此错误?
我们正在使用 PoolingNHttpClientConnectionManager。空闲期超时为 60 seconds.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();
我们在生产中经常遇到以下错误。原因是,服务器关闭了连接,而客户端正在尝试使用半关闭的陈旧连接。我们有每 80 分钟定期运行一次的驱逐策略,它将检查过期和空闲连接并关闭它们。我们仍然收到此错误。我们计划将驱逐线程间隔减少到 40 分钟。是否有任何其他解决方案可用于阻止此错误?
我们正在使用 PoolingNHttpClientConnectionManager。空闲期超时为 60 seconds.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();