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