HttpsServer вызывает 100% загрузку процессора с завитком - PullRequest
3 голосов
/ 21 июня 2019

Я создал минимальное приложение для 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();

Если удалить строку, сервер продолжит работу.

Из документов :

InДля правильного завершения каждого обмена выходной поток должен быть закрыт, даже если тело ответа не отправляется.

Я создал проект для воспроизведения проблемы.

Некоторые потенциальные подсказки, которые я нашел до сих пор:

  • Высокая загрузка ЦП происходит только при подключении к серверу с помощью curl.При соединении с Firefox загрузка ЦП остается низкой
  • Проблема не возникает с curl при использовании обычного HTTP-сервера без TLS
  • Данные, собранные с помощью Flight Recorder , указывают, что SSLEngineImpl#writeRecord в потоке HTTP-Dispatcher выделяет много объектов

Я нахожусь на Arch Linux 5.1.7 с использованием OpenJDK 12.0.1 + 12.Версия curl 7.65.1.

Это ошибка в JDK?Или я неправильно использую HttpsServer? 1048 *

1 Ответ

3 голосов
/ 23 июня 2019

Я мог бы также воспроизвести проблему.
В SSLStreams.doClosure есть бесконечный цикл - это определенно ошибка JDK.

HttpsServer нормально работал в JDK 10, но запускает цикл в JDK 11. Полагаю, проблема в том, что реализация HttpsServer не была адаптирована к политике полузакрытия TLS v1.3, появившейся в JDK 11.

К счастью, есть обходной путь. Добавьте -Djdk.tls.acknowledgeCloseNotify=true JVM вариант. С этой опцией HttpsServer будет работать как положено. Подробнее см. JDK-8208526 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...