I am using apache http client v4.5 and using it as a REST client. In some cases I recognize an error \"[read] I/O error: Read timed out\" which comes from the httpclient fra
One of the reasons for having such an error may be that the server follows the policy of closing HTTP connections upon having responded. If that is the case, then this error may be avoided by disabling connection reuse by the client, so there would be no need for the client to verify that the connection is still alive:
httpBuilder.setConnectionReuseStrategy( (response, context) -> false );
The reason is not "multithread", but "http client Pool".
It is not a error, just test the socket stale, and it is good when you want to reuse a socket. See org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10-sources.jar!/org/apache/http/pool/AbstractConnPool.java
for (;;) {
final E leasedEntry = getPoolEntryBlocking(route, state, timeout, tunit, this);
if (validateAfterInactivity > 0) {
if (leasedEntry.getUpdated() + validateAfterInactivity <= System.currentTimeMillis()) {
if (!validate(leasedEntry)) {
leasedEntry.close();
release(leasedEntry, false);
continue;
}
}
}
entryRef.set(leasedEntry);
done.set(true);
onLease(leasedEntry);
if (callback != null) {
callback.completed(leasedEntry);
}
return leasedEntry;
}
protected boolean validate(final CPoolEntry entry) {
return !entry.getConnection().isStale();
}
public boolean isStale() {
if (!isOpen()) {
return true;
}
try {
final int bytesRead = fillInputBuffer(1);
return bytesRead < 0;
} catch (final SocketTimeoutException ex) {
return false;
} catch (final IOException ex) {
return true;
}
}
org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10-sources.jar!/org/apache/http/impl/BHttpConnectionBase.java
private int fillInputBuffer(final int timeout) throws IOException {
final Socket socket = this.socketHolder.get();
final int oldtimeout = socket.getSoTimeout();
try {
socket.setSoTimeout(timeout);
return this.inbuffer.fillBuffer();
} finally {
socket.setSoTimeout(oldtimeout);
}
}
Set socket timeout to 1 ms, and read input stream, return these results:
To avoid this message, just set proper value for validateAfterInactivity , it's the min value of client socket timeout, keep-alive time(return by ConnectionKeepAliveStrategy), server connection timeout, and the delay time for idleConnectionMonitor. This does not check connection state, if connect is reset, a new connection will be created.
I'm using httpclient 4.5.2 and in my case, setting the timeouts on a request helped:
HttpPost postRequest = new HttpPost("https://...");
postRequest.setHeader(..., ...);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(1000)
.setConnectTimeout(1000)
.build();
postRequest.setConfig(requestConfig);