HttpsServer导致curl造成100%的CPU负载 [英] HttpsServer causes 100% CPU load with curl
问题描述
我围绕Java的 HttpsServer
。
I've created a minimal application around Java's HttpsServer
.
我已经安装了一个 HttpHandler
会以短文本消息回复请求:
I've installed an HttpHandler
that replies to a request with a short text message:
return exchange -> {
try {
OutputStream responseBodyStream = exchange.getResponseBody();
byte[] response = "Trouble with HTTPS and curl\n"
.getBytes(StandardCharsets.UTF_8);
exchange.getResponseHeaders().set("Content-Type", "text/plain");
exchange.sendResponseHeaders(200, response.length);
responseBodyStream.write(response);
responseBodyStream.close();
// Note that exchange.close() also closes the exchange's input stream
// and output stream
} catch (Exception e) {
log.warn("Could not handle request", e);
}
};
使用curl连接到服务器时,服务器会做出响应,但Java进程会继续使用整个内核,
When connecting to the server with curl, the server responds but the Java process keeps using an entire core, thus rendering the server unresponsive.
此行触发了该问题:
responseBodyStream.close();
如果我们删除该行,服务器将继续工作。
If we remove the line, the server keeps on working.
来自文档:
为了正确终止每次交换,输出即使未发送响应正文,流也必须关闭。
In order to correctly terminate each exchange, the output stream must be closed, even if no response body is being sent.
我已经创建了一个复制问题的项目。
I've created a project to reproduce the issue.
一些潜在的线索到目前为止,我发现:
Some potential clues I've found up till now:
- 仅当使用curl连接到服务器时,CPU使用率高。使用Firefox连接时,CPU使用率保持较低
- 使用不带TLS的常规HTTP服务器时,curl不会出现此问题
- 使用< a href = https://en.wikipedia.org/wiki/JDK_Flight_Recorder rel = nofollow noreferrer>飞行记录器表示其中的
SSLEngineImpl#writeRecord
线程HTTP-Dispatcher
分配很多对象
- High CPU usage only occurs when connecting to the server with curl. When connecting with Firefox, CPU usage stays low
- The issue does not occur with curl when using a regular HTTP server without TLS
- Data gathered using Flight Recorder indicate that
SSLEngineImpl#writeRecord
in the threadHTTP-Dispatcher
allocates a lot of objects
我在使用OpenJDK 12.0.1 + 12的Arch Linux 5.1.7。 curl的版本是7.65.1。
I'm on Arch Linux 5.1.7 using OpenJDK 12.0.1+12. The version of curl is 7.65.1.
这是JDK中的错误吗?还是我以错误的方式使用 HttpsServer
?
Is this a bug in the JDK? Or am I using HttpsServer
the wrong way?
推荐答案
我也可以重现此问题。
SSLStreams.doClosure
中有一个无限循环-这绝对是一个JDK错误。
I could also reproduce the problem.
There is an infinite loop in SSLStreams.doClosure
- this is definitely a JDK bug.
HttpsServer在JDK 10中工作正常,但在JDK 11中开始循环。我想问题是HttpsServer实现尚未适应JDK 11中出现的TLS v1.3半关闭策略。
HttpsServer worked fine in JDK 10, but starts looping in JDK 11. I guess the problem is that HttpsServer implementation has not been adapted to TLS v1.3 half-close policy appeared in JDK 11.
幸运的是,有一种解决方法。添加 -Djdk.tls.acknowledgeCloseNotify = true
JVM选项。使用此选项,HttpsServer将按预期工作。有关详细信息,请参见 JDK-8208526 。
Fortunately, there is a workaround. Add -Djdk.tls.acknowledgeCloseNotify=true
JVM option. With this option HttpsServer will work as expected. See JDK-8208526 for details.
这篇关于HttpsServer导致curl造成100%的CPU负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!