HTTP/2 и Brotli часто включают «для ускорения сайта», но прирост зависит не только от пары директив. Важны версии Apache/OpenSSL, корректный TLS (ALPN), выбранный MPM и то, какие типы контента вы реально сжимаете.
Зачем HTTP/2 и Brotli в Apache (и почему это не «галочка»)
HTTP/2 уменьшает накладные расходы HTTP/1.1: меньше конкуренции за соединения, меньше очередей на запросах, больше эффективности при загрузке множества мелких ресурсов. Основные фичи — мультиплексирование и сжатие заголовков (HPACK).
Brotli обычно сильнее уменьшает размер текстовых ответов (CSS/JS/JSON/SVG), чем gzip, при сопоставимой нагрузке на CPU на умеренных уровнях сжатия. В Apache это делается через mod_brotli, а gzip остаётся как совместимый фолбэк через mod_deflate.
Ключевой момент: браузеры почти всегда используют HTTP/2 только поверх TLS, и переключение происходит через ALPN. Поэтому «включили mod_http2» не гарантирует, что клиенты реально начали ходить по h2.
Предварительные условия: версии, OpenSSL и выбор MPM
Перед тем как трогать конфиги, быстро проверьте основу:
- Apache 2.4+ (лучше актуальные пакеты вашего дистрибутива).
- TLS-библиотека с ALPN (обычно OpenSSL 1.0.2+; в корпоративных ветках возможны бэкпорты).
- MPM: для HTTP/2 предпочтительнее
event. Наpreforkчаще упираются в память/процессы и хуже раскрывается мультиплексирование.
Проверка MPM:
apachectl -V
В выводе ищите Server MPM. Если у вас prefork, задумайтесь о переходе на event (особенно когда PHP работает через PHP-FPM, а не модулем).

Шаг 1. Включаем mod_http2 и разрешаем протокол h2
Задача на этом шаге: активировать модуль и разрешить протоколы h2 и http/1.1 (именно в таком порядке).
Debian/Ubuntu: активируем модуль
a2enmod http2
systemctl reload apache2
RHEL/Alma/Rocky: проверяем, что модуль доступен
Быстрая проверка загруженных модулей:
httpd -M | grep -E 'http2|ssl|brotli|deflate'
Для HTTP/2 по TLS должны быть видны как минимум http2_module и ssl_module.
Настройка протоколов на уровне vhost
Практичнее включать HTTP/2 в нужном виртуальном хосте на 443, чтобы случайно не затронуть служебные сайты:
<VirtualHost *:443>
ServerName example.com
Protocols h2 http/1.1
SSLEngine on
SSLCertificateFile /path/to/fullchain.pem
SSLCertificateKeyFile /path/to/privkey.pem
# остальная конфигурация...
</VirtualHost>
Директива Protocols задаёт список разрешённых протоколов. Порядок важен: ставьте h2 первым, чтобы при наличии возможности клиент выбирал HTTP/2.
ALPN: почему без него браузер остаётся на HTTP/1.1
ALPN (Application-Layer Protocol Negotiation) — расширение TLS: сервер и клиент договариваются о прикладном протоколе ещё на этапе TLS-рукопожатия. Если ALPN недоступен, браузер, как правило, не перейдёт на HTTP/2 и останется на HTTP/1.1.
Типовые причины проблем с ALPN:
- Apache связан с TLS-библиотекой без поддержки ALPN (устаревшая сборка).
- Перед Apache стоит прокси/балансировщик, который терминирует TLS без ALPN.
- Вы тестируете порт 80 и ждёте «как в браузере», хотя браузерный HTTP/2 обычно только на HTTPS.
Проверка ALPN через OpenSSL:
openssl s_client -connect example.com:443 -servername example.com -alpn h2 -tls1_2
В выводе ищите согласованный протокол ALPN: должно быть h2. Если видите http/1.1 или ALPN не упоминается — для браузеров HTTP/2, скорее всего, не включился.
h2c (HTTP/2 без TLS): где применим и почему обычно не нужен для публичного сайта
h2c — это HTTP/2 поверх обычного TCP без TLS. Встречается во внутренних сетях, лабораторных тестах и иногда между прокси и бэкендом в доверенном контуре.
Для публичного сайта h2c почти всегда лишний: браузеры не переключаются на него так же прозрачно, как на
h2по TLS через ALPN. Обычно это добавляет точки отказа и усложняет диагностику.
Если ваша цель — ускорение фронтенда в интернете, держите фокус на h2 на 443 и на корректном ALPN.
Шаг 2. Включаем Brotli в Apache (и оставляем корректный фолбэк на gzip)
Сжатие ответов в Apache обычно строят так: Brotli для клиентов с поддержкой br и gzip как запасной вариант. Главное — сжимать только текстовые MIME-типы и не загонять CPU в потолок уровнем сжатия.
Подключение модулей
Проверяем наличие модулей:
apachectl -M | grep -E 'brotli|deflate|filter'
Debian/Ubuntu (возможный вариант):
a2enmod brotli
a2enmod deflate
a2enmod headers
systemctl reload apache2
Базовая конфигурация Brotli и gzip
Пример практичной конфигурации (умеренное качество, только текстовые типы):
<IfModule brotli_module>
BrotliCompressionQuality 5
BrotliCompressionWindow 18
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
AddOutputFilterByType BROTLI_COMPRESS application/javascript application/x-javascript text/javascript
AddOutputFilterByType BROTLI_COMPRESS application/json application/xml text/xml image/svg+xml
</IfModule>
<IfModule deflate_module>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript application/x-javascript text/javascript
AddOutputFilterByType DEFLATE application/json application/xml text/xml image/svg+xml
</IfModule>
Почему BrotliCompressionQuality около 5? Обычно это хорошее соотношение «нагрузка/размер». Значения 9–11 дают небольшой дополнительный выигрыш по размеру, но на пике могут заметно поднять CPU и увеличить время генерации ответа.
Не добавляйте в сжатие уже сжатые форматы (JPEG/PNG/WebP/AVIF, zip, pdf): чаще всего это пустая трата CPU.
Кэш и Brotli: проверяем Vary
Если есть CDN/прокси/внутренний кэш, обязательно контролируйте Vary: Accept-Encoding. Иначе можно получить ситуацию, когда клиент без Brotli получает закэшированный ответ с Content-Encoding: br.
Проверка заголовков:
curl -I -H 'Accept-Encoding: br' https://example.com/
curl -I -H 'Accept-Encoding: gzip' https://example.com/
Смотрите Content-Encoding и наличие Vary. Если тема кэширования у вас сложная, полезно отдельно пройтись по политике кэша и валидаторам (ETag/Last-Modified): настройки Cache-Control и ETag для статики.

Проверяем, что HTTP/2 действительно работает
Не ориентируйтесь на субъективное «стало быстрее». Сначала подтвердите протокол и шифрование.
Проверка через curl
curl -I --http2 https://example.com/
Для диагностики рукопожатия и согласования протокола:
curl -v --http2 https://example.com/
Если --http2 не срабатывает или остаётся HTTP/1.1, возвращайтесь к проверкам ALPN и конфигурации TLS на фронте.
Логи Apache для HTTP/2
На короткое время можно поднять детализацию логов:
LogLevel http2:info ssl:warn
После диагностики верните уровень обратно, чтобы не раздувать журналы.
Что реально ускоряется (и что нет): как оценивать HTTP/2 performance
HTTP/2 сильнее заметен на страницах с большим количеством мелких ресурсов и/или на сетях с высокой задержкой (мобильные, межрегиональные). Если у вас «одна большая бандла», эффект может быть меньше.
Обычно улучшается:
- загрузка множества ресурсов без очередей на соединениях;
- стабильность на «шумных» сетях за счёт меньшего количества параллельных TCP-сессий;
- в некоторых профилях трафика — общая «соединительная» нагрузка (меньше коннектов).
Может не измениться или ухудшиться:
- если вы упираетесь в CPU на TLS и добавили тяжёлое сжатие Brotli;
- если воркеры Apache забиваются медленными клиентами (неудачные лимиты, не тот MPM);
- если основное время уходит в бэкенд/БД, а не в сеть.
Типовые ошибки и быстрые способы починки
HTTP/2 не включается, хотя mod_http2 активен
- Убедитесь, что вы на
*:443и TLS реально включён. - Проверьте ALPN через
openssl s_client. - Проверьте, что
Protocols h2 http/1.1добавлено в нужный vhost, а не «куда-то рядом».
После включения Brotli выросла нагрузка
- Снизьте
BrotliCompressionQualityдо 4–5. - Сжимайте только текстовые MIME-типы.
- Оцените, не ломает ли сжатие кэширование (частые промахи кэша приводят к большему числу компрессий).
Клиенты получают странные ответы из кэша
- Проверьте
Vary: Accept-Encodingна всех ключевых локациях. - Убедитесь, что промежуточные прокси не «склеивают» варианты br/gzip в один объект.
Рекомендованный порядок внедрения на проде
- Обновите Apache и TLS-библиотеки до актуальных пакетов.
- По возможности перейдите на MPM
event. - Включите HTTP/2 точечно на одном vhost:
Protocols h2 http/1.1. - Подтвердите ALPN и фактический протокол (curl/openssl/DevTools).
- Включите Brotli на умеренном качестве и проверьте
Content-EncodingиVary. - Снимите метрики до/после: размеры ответов, CPU, TTFB, число соединений и ошибки в логах.
Мини-чеклист
- На 443 включено
Protocols h2 http/1.1. - ALPN согласует
h2(проверено через OpenSSL). - Brotli включён только для текстовых типов и не перегружает CPU.
- Есть фолбэк на gzip через
mod_deflate. - Кэширование корректно разделяет варианты по
Vary: Accept-Encoding.
Если шаги выполнены аккуратно, связка mod_http2 + Brotli даёт ощутимый эффект: меньше сетевых накладных расходов, меньше трафика и более предсказуемая загрузка страниц, особенно на «тяжёлых» фронтендах и мобильных клиентах. Если параллельно ужесточаете безопасность TLS и заголовки, сверяйтесь с гайдом: настройки security headers для Nginx и Apache.


