我在Java19 (Temurin)下使用java.net.http.HttpClient.newHttpClient()
,并在同一个实例上执行来自不同踏板的sendAsync(...)
请求。我假设这是可以的,正如javadoc所述:
一旦建成,HttpClient是不可变的.
但是,有些请求失败了,因为:
java.io.IOException: HTTP/1.1 header parser received no bytes
奇怪的是,这取决于我请求的速度:
我已经为它写了一个测试:
private final HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://..."))
.setHeader("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofByteArray("[]".getBytes()))
.build();
@ParameterizedTest
@ValueSource(ints = {3, 5})
void httpClientTest(int intervalSeconds) throws Exception {
HttpClient httpClient = HttpClient.newHttpClient();
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
}
我已经尝试过以下几种方法:
curl
执行同样的操作。无论我尝试什么时间间隔,都不会有请求失败。所以这可能不是服务器的问题。HttpClient.newHttpClient()
。无论间隔多久,任何请求都不会失败。因此,这可能不是服务器的问题,而是HttpClient
的内部状态(尽管它声称是不可变的?)。您知道我可以做什么,而不需要为每个请求创建一个新的HttpClient
吗?
发布于 2022-10-28 09:43:36
下面是记录的答案:java.net.HttpClient
的默认HTTP/1.1 keepAlive时间很长,比通常配置的服务器要长。这通常导致服务器在客户机之前关闭空闲的HTTP/1.1连接。如果服务器在客户端试图重用连接的同时关闭连接,则可能引发一些IOException
。
如果这种异常被观察得太频繁,应用程序应该考虑将客户机中的默认keepAlive时间调整为比其连接到的服务器所使用的值更短的值。HttpClient HTTP/1.1 keepAlive时间的默认值可以是在命令行上指定 with:-Djdk.httpclient.keepalive.timeout=duration-in-seconds
因此,例如,如果服务器配置为keepAlive时间为5s,则可以考虑在客户端的java命令行上提供-Djdk.httpclient.keepalive.timeout=3
或-Djdk.httpclient.keepalive.timeout=4
。
https://stackoverflow.com/questions/74215117
复制相似问题