Java ApacheHTTP客户端打印“;[读取]I/O错误:读取超时“&引用;
我正在使用ApacheHTTP客户机v4.5,并将其用作REST客户机。在某些情况下,当httpclient框架读取接收到的内容并将其显示为最后一条消息时,我会识别出一个错误“[read]I/O error:read timed out” 这似乎没有影响,但我想知道是否有人知道它来自哪里,以及如何解决。根据以下线程()的说法,“mutlithread”配置似乎存在问题 然而,我只使用http客户机的默认配置,当我使用v4版本时,我不知道如何将“multithreaded”设置为false,以查看它是否有任何区别 我还试图设置超时,但没有起到任何作用 有什么提示吗 日志:Java ApacheHTTP客户端打印“;[读取]I/O错误:读取超时“&引用;,java,multithreading,timeout,httpclient,apache-httpcomponents,Java,Multithreading,Timeout,Httpclient,Apache Httpcomponents,我正在使用ApacheHTTP客户机v4.5,并将其用作REST客户机。在某些情况下,当httpclient框架读取接收到的内容并将其显示为最后一条消息时,我会识别出一个错误“[read]I/O error:read timed out” 这似乎没有影响,但我想知道是否有人知道它来自哪里,以及如何解决。根据以下线程()的说法,“mutlithread”配置似乎存在问题 然而,我只使用http客户机的默认配置,当我使用v4版本时,我不知道如何将“multithreaded”设置为false,以查看
我使用的是httpclient 4.5.2,在我的例子中,设置请求的超时有助于:
HttpPost postRequest = new HttpPost("https://...");
postRequest.setHeader(..., ...);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(1000)
.setConnectTimeout(1000)
.build();
postRequest.setConfig(requestConfig);
出现此类错误的原因之一可能是服务器在响应后遵循关闭HTTP连接的策略。如果是这种情况,则可以通过禁用客户端的连接重用来避免此错误,因此客户端无需验证连接是否仍处于活动状态:
httpBuilder.setConnectionReuseStrategy( (response, context) -> false );
原因不是“多线程”,而是“http客户端池”
这不是一个错误,只是测试套接字是否过时,当您想要重用套接字时,这是一个好方法。
看见
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;
}
}
将套接字超时设置为1毫秒,读取输入流,返回以下结果:
这不会检查连接状态,如果重置连接,将创建新连接。它不会打印任何内容。你的代码会打印出来。不清楚您在问什么,您使用的是哪个版本的apache http客户端?我在问是否有人知道为什么会出现错误消息“[read]I/O error:read timed out”。我也看到了这一点。还值得注意的是,没有引发任何异常,也没有像调试一样记录为错误。这似乎与多线程使用HttpClient的连接池有关,但实际上不会导致问题。您也可以使用新的org.apache.http.impl.noConnectionReuseStragy()而不是创建自己的(尽管很简单)兰姆达:谢谢
httpBuilder.setConnectionReuseStrategy( (response, context) -> false );
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;
}
}
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);
}
}