Itc*_*chy 0 java-http-client java-19
我java.net.http.HttpClient.newHttpClient()在 Java 19 (Temurin) 下使用,并sendAsync(...)在同一实例上执行来自不同步骤的请求。我认为这是可以的,正如 javadoc 所说:
一旦构建,HttpClient 就是不可变的......
但是,某些请求会失败并显示以下信息:
java.io.IOException: HTTP/1.1 header parser received no bytes
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这取决于我的请求的速度:
我为它写了一个测试:
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();
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试过以下操作:
curl在命令行上执行相同的操作。无论我尝试什么时间间隔,都没有请求失败。所以应该不是服务器的问题。HttpClient.newHttpClient()为每个请求创建一个。无论时间间隔如何,请求都不会失败。所以这可能不是服务器的问题,而是服务器的内部状态的问题HttpClient(尽管它声称是不可变的?)。您知道我可以做什么,而不需要HttpClient为每个请求创建一个新的请求吗?
以下是记录的答案:java.net.HttpClientHTTP/1.1 默认的 keepAlive 时间很长,比通常服务器配置的时间要长。这通常会导致服务器先于客户端关闭空闲的 HTTP/1.1 连接。如果服务器在客户端尝试重用连接的同时关闭连接,则IOException可能会引发一些问题。
如果此类异常出现得太频繁,应用程序应考虑将客户端中的默认 keepAlive 时间调整为比其连接到的服务器正在使用的时间短的某个值。可以在命令行上指定HttpClient HTTP/1.1 keepAlive 时间的默认值:-Djdk.httpclient.keepalive.timeout=duration-in-seconds
例如,如果服务器配置的 keepAlive 时间为 5 秒,您可以考虑在客户端的 java 命令行上提供-Djdk.httpclient.keepalive.timeout=3或。-Djdk.httpclient.keepalive.timeout=4
| 归档时间: |
|
| 查看次数: |
1356 次 |
| 最近记录: |