ADG Оставить заявку
Блог Инфраструктура 5 мин чтения

HTTP/2 на production nginx: включаем на клиентских серверах и замеряем эффект

Включаем HTTP/2 на production nginx-серверах клиентов после тестирования. На страницах со множеством ресурсов latency падает на 30-40%. Нюансы: TLS обязателен, SNI, без keep-alive хаков.

Контекст момента

HTTP/2 в nginx 1.9.5+ и Apache 2.4.17+ достиг production-ready состояния к началу 2016 года и готов к широкому внедрению

Поддержка HTTP/2 в nginx появилась в версии 1.9.5 ещё осенью прошлого года - как экспериментальный модуль, который надо было собирать с флагом --with-http_v2_module. В дистрибутивных пакетах стабильных веток он тихо дозревал, и к апрелю 2016-го ситуация такая: nginx 1.9.x из mainline или 1.10.x из свежего stable собраны с HTTP/2 из коробки, и реально ставить его на production - нормальная практика.

Мы отложили это с осени не потому что боялись, а потому что хотели пройти с новым протоколом нормальный цикл: сначала понять, что именно изменится и на каких сценариях, потом посмотреть на чужой опыт, потом staging, потом production. Сейчас - production.

Что нужно для HTTP/2 на nginx

Первое и главное: HTTP/2 работает только поверх TLS. Формально протокол позволяет работать в cleartext (h2c), но ни один браузер это не поддерживает. На практике это означает: нет TLS - нет HTTP/2. Хорошая новость: после Let's Encrypt GA в начале апреля у нас TLS есть на всех клиентских доменах, где мы ведём nginx. Кто не успел поставить сертификат - для него HTTP/2 просто не актуален, и это дополнительный аргумент закрыть HTTP.

Второе: нужен SNI-совместимый стек. Со стороны клиента это все современные браузеры. Проблема только в очень старых клиентах без SNI - в 2016 году это в основном IE 8 на Windows XP. Для этой аудитории сервер продолжает говорить на HTTP/1.1 без каких-либо изменений: если браузер не умеет h2 по ALPN, сервер отдаёт 1.1. Деградация прозрачная.

Третье: OpenSSL 1.0.2+ и NPN/ALPN. Без ALPN (Application-Layer Protocol Negotiation) согласование HTTP/2 не работает в штатном режиме. Nginx проверить просто:

nginx -V 2>&1 | grep -o 'OpenSSL [^ ]*'

На CentOS 7 с системным OpenSSL 1.0.1 - будет NPN, без ALPN. Это работает для большинства браузеров (Chrome, Firefox поддерживают NPN), но новые версии Chrome и Edge требуют ALPN. На Ubuntu 15.10+ OpenSSL 1.0.2 идёт в базе - там всё ок.

Включение: три строки в конфиге

В конфиге виртуального хоста меняется одна директива:

listen 443 ssl http2;

И всё. nginx начинает анонсировать h2 через ALPN/NPN, браузеры с поддержкой HTTP/2 переключаются автоматически.

Что при этом перестаёт быть нужным - вот что интереснее.

Keepalive-хаки. Долгое время нормальная практика с HTTP/1.1 - это агрессивный keepalive, connection pooling, выставление keepalive_timeout и keepalive_requests с запасом, чтобы браузер держал соединение и переиспользовал его для параллельных запросов. HTTP/2 решает ту же проблему мультиплексированием: несколько запросов летят по одному соединению одновременно. Keepalive-параметры в блоке http2 не вредят, но смысл у них другой.

Domain sharding. Классический трюк - разносить статику по поддоменам (static1.example.ru, static2.example.ru) чтобы обойти ограничение браузера на 6 параллельных соединений к одному домену. При HTTP/2 это не только бесполезно, но и вредно: каждый отдельный домен требует отдельного TLS handshake, а мультиплексирование в рамках одного соединения эффективнее параллельных соединений к разным доменам. Убирать sharding при переходе на h2 - осмысленное действие.

Спрайты и конкатенация ресурсов. Логика та же: склеивали CSS/JS в один файл или делали CSS-спрайты из иконок, чтобы уменьшить число запросов. HTTP/2 с server push и мультиплексированием делает «много мелких запросов» дешевле «одного большого». Переделывать под это уже существующую сборку - нецелесообразно прямо сейчас, но для новых проектов это меняет логику фронтенд-сборки.

Что замерили

Запускали managed-сопровождение на нескольких клиентских сервисах последовательно. Брали страницы с реальной нагрузкой по числу ресурсов: корпоративный сайт с несколькими десятками CSS/JS/image-запросов на странице, интранет-портал, публичный каталог.

Измерения - WebPageTest с тремя запусками подряд, смотрели на Time to First Byte и полное время загрузки страницы на медленном соединении (эмуляция 3G) и на нормальном широкополосном. Разница в зависимости от страницы:

  • На страницах с 30+ ресурсами - снижение total load time на 30-40% при эмуляции медленного соединения. Именно здесь мультиплексирование даёт максимальный эффект: браузер не ждёт очереди, все запросы летят параллельно по одному соединению.
  • На страницах с несколькими тяжёлыми файлами - эффект значительно меньше. Если страница - это один большой бандл JS и одна картинка, HTTP/2 почти ничего не меняет.
  • TTFB - не изменился или изменился в пределах погрешности. HTTP/2 ускоряет параллельную загрузку ресурсов, но не обработку запроса на сервере.

Предсказуемые результаты, никаких сюрпризов. Главный вывод: HTTP/2 - это инструмент для «много мелких запросов», а не универсальное ускорение.

Что с Apache

Apache 2.4.17+ поддерживает HTTP/2 через модуль mod_http2. На практике с Apache история немного сложнее: из-за архитектуры prefork/worker нужно использовать event MPM, иначе mod_http2 не работает или работает некорректно. На CentOS 7 из базового репозитория Apache 2.4.6 - без HTTP/2. Нужен либо обновлённый пакет, либо сборка из исходников. На Ubuntu 15.10 Apache 2.4.12 в репозитории - mod_http2 есть.

На клиентских серверах с Apache мы включение HTTP/2 пока придерживаем: либо версия не та, либо MPM требует перепроверки. nginx-серверы - готовы и включены.

Обратной дороги нет, и это хорошо

Переключение обратно - одна строка в конфиге. Ничего не сломается. Браузеры без HTTP/2 продолжают работать на 1.1, это не экспериментальный фичер с рисками - это изменение в транспортном протоколе, прозрачное для прикладного кода. Единственное обязательное условие (TLS) уже выполнено. Откладывать незачем.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.