Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

We are getting the below error frequently in our production. The reason is, server closes the connection and the client is trying with half closed stale connection. we have eviction strategy which runs every 80 minutes periodically which will check for expired and idle connections and close them. still we are getting this errors. we are planning to reduce the eviction thread interval to 40 minutes. is there any other solution available to stop this errors?

We are using PoolingNHttpClientConnectionManager. idle period timeout is 60 seconds.httpasyncclient version is 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)
like image 346
Sudha Rajamanickam Avatar asked Mar 21 '26 15:03

Sudha Rajamanickam


1 Answers

There are two options:

  1. Define a finite TTL (total time to live) limit for all connections at the connection manager construction time
  2. Use a custom ConnectionKeepAliveStrategy implementation to enforce a relative expiration time for persistent connections.

Here is example of HttpAsyncClient configuration that enforces a total time to live limit of 2 minute and relative expiration time of 30 seconds

Please note this may not completely eliminate the issue as both endpoints, the client and the server, may close connections at any point of time without a prior handshake.

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();
like image 148
ok2c Avatar answered Mar 23 '26 05:03

ok2c



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!