Прикручуємо до Nginx патч для динамічного розміру TLS records від Cloudflare

Якщо ви використовуєте Nginx для термінації TLS-трафіку, то можете поліпшити час відповіді сервера за допомогою патчів від Cloudflare. Подробиці під катом.



TLS і TCP
Як відомо, дані в Інтернеті передаються з використанням багатошарового стека протоколів. Зараз нас цікавить взаємодія TCP і TLS. Основне завдання TCP — надійна доставка пакетів у вихідному порядку. Якщо у нас є сервіс, що використовує SSL (HTTPS-сайт), то всі зашифровані TLS дані будуть відправлятися з допомогою TCP.

На рівні TCP: відразу після підключення, сервер може відправити не більше, ніж initcwd пакетів (для старих систем це 3 пакету, для нових — 10). Далі сервер буде чекати підтвердження (ACK) від клієнта і поступово кількість пакетів у вікні відправлення буде зростати, а з'єднання буде збільшувати свою пропускну здатність.

У випадку зі звичайним HTTP-трафіком все відмінно: з кожним новим пакетом приходять дані, які браузер може використовувати.

Проблема c TLS
Якщо ми використовуємо SSL, то Nginx використовує спеціальний буфер (розмір задається директивою ssl_buffer_size), який управляє розміром 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 не існує.

Динамічний розмір TLS record
Тут на допомогу приходить Cloudflare зі своїм набором патчів.

З використанням цих патчів ми отримуємо підтримку динамічного розміру TLS record.

На свіжих з'єднаннях розмір запису встановлюється не більше розміру одного пакета, після проходження певної кількості записів розмір можна збільшити до 3 TCP-пакетів, а далі вже до максимального розміру (16k). Після простою з'єднання процес починається знову. Всі параметри цього процесу налаштовуються.

Застосування патчів
Щоб отримати нову функціональність, потрібно застосувати патчі і зібрати Nginx. Про складання Nginx з OpenSSL я вже писав раніше, тому зупинимося на процесі застосування патчів.

Для застосування патчів потрібно зайти на сторінку github.

На цій сторінці потрібно вичленувати окремі патчі для кожного файлу. Запис самого патча починається так:

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, все вийшло).

Налаштування Nginx
З патчем приходять нові налаштування. Отримуємо приблизно такі значення:

# Початковий розмір запису, приблизно 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;

Докладно можна почитати у вихідній статті блогу Cloudflare.

Про самому принципі оптимізації TLS record size можна почитати в книзі HPBN.
На цьому у мене все, поки що впровадили у себе, тестуємо. Якщо у вас вже є досвід налаштування, прохання поділитися в коментарях.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.