nginx: HTTP/2 и kTLS
Maxim Dounin
mdounin на mdounin.ru
Пн Янв 8 21:04:16 UTC 2024
Hello!
On Sun, Jan 07, 2024 at 10:39:00AM +0300, izorkin на gmail.com wrote:
> Доброе утро.
>
> При использовании kTLS и sendfile наблюдается просадка производительности
> при отдаче статических файлов, например при видео-стриминге. Одним из
> вариантов решения является перенести статический файлы на другой хост и
> использовать там только протоколы HTTP/1.1 и/или HTTP/3. Либо усложнять
> логику работы в блоке location.
>
> Не все сервисы позволяют выводить статику на отдельный хост, либо могут
> иметь сложную конфигурацию nginx. Например web-сервис Peertube имеет
> множество блоков location и использует различные условия if:
> https://github.com/Chocobozzz/PeerTube/blob/develop/support/nginx/peertube
>
> Обычному пользователю будет сложнее с этим разобраться и добавить
> дополнительные блоки для исключения работы протокола HTTP/2 через kTLS.
> Вполне легко можно запутаться и нарушить логику работы сайта.
>
> Хотелось бы иметь более простой и универсальный способ отключения
> обработки протокола HTTP/2 через kTLS.
>
> Предполагаю, что перед передачей шифрования ядру системы сейчас nginx
> проверяет наличие ssl и параметра sendfile. Можно ли добавить дополнительное
> условие, которое проверяет дополнительный параметр, который указывает
> какой протокол исключить из обработки шифрования ядром?
>
> По итогу получится примерно такой вариант конфигурации:
> server {
> listen 0.0.0.0:443 quic reuseport ;
> listen 0.0.0.0:443 ssl reuseport ;
> http2 on;
> http3 on;
> ssl_conf_command Options KTLS;
> disable_ktls_for_protocol http2;
> ...
>
> Мне кажется, что такой вариант эффективнее, чем добавлять условие if с
> rewrite и дополнительный блок location.
Как я уже писал ранее,
1. Дело не в kTLS, kTLS работает для HTTP/2 точно так же, как и
для HTTP/1.x. Просто в отсутствии акселераторов - kTLS сам по
себе не даёт примерно ничего. Дело в sendfile(), который при
включённом kTLS начинает работать в том числе для HTTP/2, но для
HTTP/2 он работает плохо из-за фрейминга.
2. Смысла в таком решении примерно ноль, потому что типичный
браузер всё равно соединится по HTTP/2 (или по HTTP/3). То есть с
тем же успехом можно просто выключить sendfile (и/или kTLS),
результат не будет отличаться.
Если хочется, чтобы было быстро - надо выносить (большую) статику в
отдельный домен, где разрешать только HTTP/1.x, и соответственно
включать sendfile и kTLS.
Впрочем, насколько быстро - это отдельный вопрос. Скорее всего на
линуксе примерно те же результаты можно получить, просто подняв
размер output_buffers (http://nginx.org/r/output_buffers).
--
Maxim Dounin
http://mdounin.ru/
Подробная информация о списке рассылки nginx-ru