On Wed, 2015-05-13 at 20:58 +0000, Mark A. Claassen wrote:
> The 4.4.1 code doesn't seem to help.
>
> I have been able to reproduce the issue more regularly now. It seems to have
> to do with keep-alives and if the client takes longer to read the message
> than the keep alive value.
>
Hi Mark
Then, it is all very simple. There are several ways to make HttpClient
either discard potentially half-closed connections, test them for
'staleness' or automatically recover from NoHttpResponseException.
> In my test case I open the connection, read all the data, sleep for a while,
> then close the connection.
> If my sleep is a bit longer than the keep-alive value, I will get a
> org.apache.http.NoHttpResponseException. If my sleep value is larger, I will
> get a java.net.SocketException.
> (Keep-Alive is 5000 millis. If I sleep for 6000, I will get a
> NoHttpResponseException. If I sleep for 11000, I will get a SocketException.
>
The default maximum inactivity period used by the pooling connection
manager is exactly 5000 ms. Please try reducing this value to, say, 2000
ms
---
PoolingHttpClientConnectionManager cm = new
PoolingHttpClientConnectionManager();
cm.setValidateAfterInactivity(2000);
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(cm)
.build();
---
This should make the problem go away.
> If I use the NoConnectionReuseStrategy, the problem goes away.
>
> Is something set up for my keep alives? I put some breakpoints in
> CPool.java. I can see connections being created, but the validate() method
> of CPool is never getting called.
>
> I am curious this part of AbstractConnPool.java. This seems like if the
> server invalidated a connection early, the validate check would never happen.
>
> } else if (this.validateAfterInactivity > 0) {
> if (entry.getUpdated() + this.validateAfterInactivity
> <= System.currentTimeMillis()) {
> if (!validate(entry)) {
> entry.close();
> }
> }
> }
> Scenario:
> Server sends data.
> Client reads packet, processes it for 6 seconds
> Server senses that inactivity for 5 seconds, closes connection
> Client closes connection and places entry back in the pool
> Connection immediately leased to another thread
> Time between release and close is almost nothing
> Pool releases stale connection.
>
You can force TTL (total time to live) for connections to avoid this
problem
---
PoolingHttpClientConnectionManager cm = new
PoolingHttpClientConnectionManager(3000, TimeUnit.MILLISECONDS);
cm.setValidateAfterInactivity(1000);
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(cm)
.build();
---
Hope this helps
Oleg
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]