【发布时间】:2019-11-04 14:12:18
【问题描述】:
我已经围绕 Java 的 HttpsServer 创建了一个最小的应用程序。
我已经安装了一个HttpHandler,它通过一条短信回复请求:
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 进程会继续使用整个内核,从而导致服务器无响应。
正是这一行触发了问题:
responseBodyStream.close();
如果我们删除该行,服务器会继续工作。
来自docs:
为了正确终止每个交换,必须关闭输出流,即使没有发送响应正文。
我已经创建了a project to reproduce 问题。
到目前为止我发现的一些潜在线索:
- 只有在使用 curl 连接到服务器时才会出现高 CPU 使用率。与 Firefox 连接时,CPU 使用率保持在较低水平
- 使用没有 TLS 的常规 HTTP 服务器时,curl 不会出现此问题
- 使用Flight Recorder 收集的数据表明线程
HTTP-Dispatcher中的SSLEngineImpl#writeRecord分配了很多对象
我在 Arch Linux 5.1.7 上使用 OpenJDK 12.0.1+12。 curl的版本是7.65.1。
这是 JDK 中的错误吗?还是我用错了HttpsServer?
【问题讨论】:
标签: java performance curl https server