- PVSM.RU - https://www.pvsm.ru -
Если вы используете Nginx для терминации TLS-трафика, то можете улучшить время ответа сервера с помощью патчей от Cloudflare. Подробности под катом.
Как известно, данные в Интернете передаются с использованием многослойного стека протоколов. Сейчас нас интересует взаимодействие TCP и TLS. Основная задача TCP — надёжная доставка пакетов в исходном порядке. Если у нас есть сервис, использующий TLS (HTTPS-сайт), то все зашифрованные TLS данные будут отправляться с помощью TCP.
На уровне TCP: cразу после подключения, сервер может отправить не больше, чем initcwd пакетов (для старых систем это 3 пакета, для новых — 10). Далее сервер будет ждать подтверждения (ACK) от клиента и постепенно количество пакетов в окне отправки будет расти, а соединение будет увеличивать свою пропускную способность.
В случае с обычным HTTP-трафиком все отлично: с каждым новым пакетом приходят данные, которые браузер может использовать.
Если мы используем TLS, то Nginx использует специальный буфер (размер задаётся директивой ssl_buffer_size [1]), который управляет размером TLS record size. Браузер (клиент) может использовать данные только после получения TLS record полностью. При этом максимальный (и дефолтный в Nginx) размер ssl_buffer_size составляет 16k.
Так как начальное окно для отправки пакетов = 10, то мы можем получить примерно 14k трафика, что меньше TLS record (16k). Это может вызывать задержки в получении полезного контента.
А если вы используете HTTP/2, то стоит обратить внимание на настройку http2_chunk_size (по умолчанию 8k) — она устанавливает максимальный размер части, на которое делится тело ответа. При этом используется только одно подключение к серверу, поэтому в этом TCP соединении передаётся одновременно множество ресурсов, что увеличивает вероятность возникновения задержек.
Самое простое, что можно сделать — уменьшить ssl_buffer_size, например до 8k или 12k. Это можно сделать в стандартной версии Nginx. Однако, при пересылке большого количества данных эффективность будет ниже (выше накладные расходы).
Получается, что идеального ssl_buffer_size не существует.
Здесь на помощь приходит Cloudflare со своим набором патчей [2].
С использованием этих патчей мы получаем поддержку динамического размера TLS record.
На свежих соединениях размер записи устанавливается не больше размера одного пакета, после прохождения некоторого количества записей размер можно увеличить до 3 TCP-пакетов, а далее уже до максимального размера (16k). После простоя соединения процесс начинается снова. Все параметры этого процесса настраиваются.
Чтобы получить новую функциональность, нужно применить патчи и собрать Nginx. О сборке Nginx с OpenSSL я уже писал ранее [3], поэтому остановимся на процессе применения патчей.
Для применения патчей нужно зайти на страницу github [2].
На этой странице нужно вычленить отдельные патчи для каждого файла. Запись самого патча начинается так:
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
Из этой записи понятно, к чему относится этот патч (в данном случае это src/event/ngx_event_openssl.c).
Копируем текст патча в файл (например, openssl.c.patch) и кладём рядом с файлом исходника.
Применяем патч следующей командой:
patch ngx_event_openssl.c < openssl.c.patch
Так проходимся по всем файлам патча (всего должно быть 4 файла).
Ну и собираем Nginx как обычно (я использовал 1.11.2, всё получилось).
С патчем приходят новые настройки. Получаем примерно такие значения:
# Начальный размер записи, примерно 1 пакет
ssl_dyn_rec_size_lo 1369;
# Промежуточный размер записи, 3 пакета
ssl_dyn_rec_size_hi 4229;
# Количество записей для перехода к следующему размеру
ssl_dyn_rec_threshold 20;
# Время простоя для сброса размера до начального
ssl_dyn_rec_timeout 10;
# Стандартный буфер, ставим максимальное значение
ssl_buffer_size 16k;
Подробно можно почитать в исходной статье [4] блога Cloudflare.
О самом принципе оптимизации TLS record size можно почитать в книге HPBN [5].
На этом у меня всё, пока внедрили у себя, тестируем. Если у вас уже есть опыт настройки, просьба поделиться в комментариях.
Автор: Nickmob
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nginx/160134
Ссылки в тексте:
[1] ssl_buffer_size: http://nginx.org/ru/docs/http/ngx_http_ssl_module.html#ssl_buffer_size
[2] набором патчей: https://github.com/cloudflare/sslconfig/blob/master/patches/nginx__dynamic_tls_records.patch
[3] ранее: https://habrahabr.ru/post/301452/
[4] статье: https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/
[5] книге HPBN: https://hpbn.co/transport-layer-security-tls/#optimize-tls-record-size
[6] Источник: https://habrahabr.ru/post/306142/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.