awesome-everything EN
↑ Обратно к восхождению

Сети и протоколы

HTTP/3 в продакшне: внутренности QUIC, fallback и наблюдаемость

Суть Запуск HTTP/3 в продакшне требует понимания управления перегрузкой QUIC в userspace, механики ALPN-переговоров о версии, тихого fallback и метрик, которые показывают, когда UDP блокируется.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 18 min

Ваш edge-сервис включает HTTP/3. Однажды утром дашборд ALPN показывает: доля h3 упала с 40% до 5%. Ошибок в логах приложения нет. Пользователи не звонят. Что сломалось? Это инцидент HTTP/3 в продакшне — и путь диагностики совсем не похож на TCP-outage.

TCP HOL-блокировка: точный механизм

Антагонист HTTP/2 — контракт доставки TCP. TCP гарантирует доставку в порядке байтового потока. Когда сегмент с байтами 50 000–50 099 потерян, TCP буферизует все последующие байты до повторной передачи потерянного сегмента. Буфер приёма TCP в ядре заполняется; ни один байт не движется к приложению. На уровне HTTP/2 поток #1 может использовать байты 50 000–50 099, поток #2 — байты 50 100–50 199: оба встают на ожидание повторной передачи.

Метрика: при 1% потере пакетов и RTT 100 мс ожидается примерно одно событие потери на 100 пакетов, с задержкой ~100 мс на событие. При 50 параллельных потоках эта задержка затрагивает все 50. На каналах с высокими потерями (мобильная сеть 0,5–2%, спутник 2–5%) HTTP/2 ощутимо проигрывает HTTP/1.1 с 6 параллельными TCP-соединениями — потому что параллельные соединения имеют независимые домены восстановления потерь.

Независимость потоков QUIC: точный механизм

QUIC нумерует пакеты, а не байтовые смещения единого потока. Каждый QUIC-пакет подтверждается отдельно. Каждый поток отслеживает, какие пакеты несли его фреймы и какие ещё в полёте.

Когда пакет N потерян:

  1. QUIC повторно передаёт конкретные фреймы потоков A и C, которые были в пакете N.
  2. Потоки B, D и E — чьи фреймы были в других пакетах — продолжают отправлять и получать.
  3. Прикладной уровень для потока B не видит прерывания.

Цена: заголовки QUIC-фреймов добавляют накладные расходы (stream ID, смещение, длина на фрейм — ~8–10 байт каждый, против TCP-сегмента без накладных расходов на поток). Состояние на соединение тяжелее. Но на каналах с потерями выигрыш решающий.

HPACK vs QPACK: зависимость от порядка

HPACK (RFC 7541) поддерживает динамическую таблицу, индексированную по последовательности вставок. Запись под индексом 62 — это 62-я пара (имя, значение), вставленная с начала соединения. HEADERS-фрейм, ссылающийся на индекс 62, должен быть обработан после фрейма, который вставил индекс 62.

На TCP: фреймы приходят в порядке — HEADERS-фрейм, добавляющий индекс 62, всегда приходит раньше HEADERS-фреймов, ссылающихся на него. Ограничение порядка невидимо.

На QUIC: потоки доставляют фреймы независимо. HEADERS-фрейм в потоке #3 может прийти раньше HEADERS-фрейма в потоке #1, который добавил бы индекс 62. Если HEADERS потока #3 ссылается на индекс 62, декодирование провалится или заблокируется.

Решение QPACK (RFC 9204):

  • Encoder stream — выделенный однонаправленный QUIC-поток несёт вставки в динамическую таблицу. Этот поток доставляет обновления таблицы в порядке.
  • Decoder stream — несёт подтверждение о том, какие записи таблицы были обработаны.
  • HEADERS-фреймы — ссылаются только на записи, которые энкодер знает как подтверждённые на decoder stream. HEADERS-фрейм в потоке #3 никогда не ссылается на запись, которая может ещё не быть в таблице декодера.

Результат: HEADERS-фреймы одного потока никогда не могут блокироваться HEADERS-фреймами другого потока — независимость потоков QUIC сохраняется на уровне сжатия заголовков.

HTTP/3 метрики в продакшне (апрель 2026)
Глобальная доля HTTP/3-трафика
21.1% (Cloudflare Radar)
Сайты, рекламирующие HTTP/3
38.8% (W3Techs)
Google, Meta, Cloudflare, Akamai — доля h3
>50% их трафика
Типичный процент блокировки UDP/443 корпоративными firewall'ами
5–15% корпоративных путей
Стоимость fallback HTTP/3 → HTTP/2 в RTT
+1 RTT при первом визите
Окно риска повтора 0-RTT данных
Срок действия сессионного тикета

Переговоры о версии: ALPN и цепочка fallback

Для HTTP/1.1 и HTTP/2: ALPN (RFC 7301) — расширение TLS. Во время TLS-хендшейка клиент шлёт список поддерживаемых протоколов (["h2", "http/1.1"]). Сервер выбирает один. Без дополнительных round-trip — переговоры о версии бесплатны внутри хендшейка.

Для HTTP/3: переговоры двухэтапные, потому что QUIC/UDP — другой транспорт:

  1. Первое соединение использует TCP-based HTTP/1.1 или /2.
  2. Ответ сервера включает Alt-Svc: h3=":443"; ma=86400 (или HTTPS/SVCB DNS-запись). Браузер сохраняет эту подсказку.
  3. Последующие соединения к этому origin: браузер пробует QUIC/UDP первым, с TLS ALPN, выбирающим h3.
  4. Если UDP/443 заблокирован (QUIC-хендшейк не прошёл): браузер помечает этот origin как «h3 недоступен» на период cooldown и откатывается к TCP-based HTTP/2.

Fallback тихий — пользователи не видят ошибок, но операторы должны мониторить метрики ALPN-распределения. Пик h3→h2 fallback — сигнал изменения сетевого пути, блокирующего UDP/443.

Коалесценция соединений

Несколько origin’ов, разделяющих один IP edge-сервера и охваченных TLS-сертификатом, могут использовать одно HTTP/2 или HTTP/3 соединение — коалесценция соединений. Пример: cdn.example.com и api.example.com оба резолвятся в один IP, и edge-сертификат покрывает оба имени в SAN (Subject Alternative Names). Chrome и Firefox коалесцируют: одно QUIC-соединение обслуживает запросы к обоим hostname’ам.

Это экономит стоимость хендшейка на страницах, загружающих ресурсы с нескольких origin’ов на одном CDN. Подводный камень: если список SAN сертификата не включает один из коалесцируемых hostname’ов (мискофигурация), браузер открывает отдельное соединение — тихая регрессия задержки. Мониторьте количество соединений на origin; внезапный рост сигнализирует о сбое коалесценции.

Управление перегрузкой в QUIC userspace

Управление перегрузкой TCP (CUBIC, BBR, Reno) работает в ядре операционной системы. QUIC реализует управление перегрузкой в userspace — внутри приложения или библиотеки QUIC.

Следствия:

  • Гибкость: операторы могут настраивать или менять алгоритмы на соединение, на приложение или на класс трафика без изменения ядра.
  • CPU-стоимость: вычисления управления перегрузкой выполняются в процессе, конкурируя с кодом приложения за CPU. При большом числе соединений это ощутимо.
  • Наблюдаемость: каждое QUIC-соединение должно экспортировать свои измерения окна перегрузки, скорости потерь и RTT. TCP в ядре экспортирует их через /proc/net/tcp и ss; QUIC требует хуков телеметрии на соединение.

Формат qlog IETF (JSON-лог событий на соединение) — инструмент глубокой отладки для QUIC. Для продакшна экспортёры Prometheus/OTel агрегируют QUIC-метрики по соединениям.

0-RTT replay: операционный риск

Возобновление 0-RTT (через TLS-сессионные тикеты) позволяет браузеру отправить HTTP-запрос в самом первом QUIC-пакете, до завершения хендшейка. Это экономит один RTT (~50–300 мс на дальних каналах).

Риск: 0-RTT данные могут быть повторены сетевым злоумышленником. Атакующий, перехвативший первый QUIC-пакет, может переслать его, заставив сервер обработать запрос второй раз. Для GET-запросов (идемпотентных, без побочных эффектов) это безвредно. Для POST (создание заказа, отправка платежа) — катастрофа.

Требования для продакшна:

  • Сервер должен отслеживать и отклонять повторённые 0-RTT данные (через anti-replay токены — RFC 9001 § 9.2).
  • Серверы должны отвечать 425 Too Early для небезопасных методов в 0-RTT.
  • Хранилище anti-replay токенов: ограниченное; на крупных распределённых развёртываниях нужен общий кэш (Redis) для обнаружения повторов на разных edge-узлах.
Проследи
1/4

Диагностика: доля HTTP/3-трафика сервиса упала с 40% до 5% за ночь.

1
Step 1 of 4
Шаг 1: какую метрику проверить первой?
2
Locked
Шаг 2: ALPN показывает h3 с 40% → 0% и h2 поглотил всё. Что скорее всего произошло?
3
Locked
Шаг 3: tcpdump на edge-узле показывает входящие UDP/443-пакеты близко к нулю. Подтвердите гипотезу. Как найти блок?
4
Locked
Шаг 4: пока сетевая команда координирует исправление, что делать со стороны клиента?
Найди ошибку

Дашборд наблюдаемости: обнаружение пика HTTP/3-fallback

log
# Prometheus-метрики с CDN edge, апрель 2026

## Распределение ALPN-протоколов (скользящее среднее 5 минут)
tls_alpn_protocol{protocol="h3"} 21.1%     # Нормальный базовый уровень
tls_alpn_protocol{protocol="h2"} 51.3%
tls_alpn_protocol{protocol="http/1.1"} 27.6%

## Скорость fallback (h3 пробовался, но откатился на h2)
http3_to_http2_fallback_rate 0.8%          # Базовый уровень: нормальные потери/блокировка ISP

## В 14:35 UTC 2026-04-15 срабатывает alert: скорость fallback растёт
http3_to_http2_fallback_rate 18.2%         # 23x нормы
tls_alpn_protocol{protocol="h3"} 1.3%      # Упал с 21.1%

## Геолокационная разбивка показывает: пик сконцентрирован
fallback_rate{region="US-Northeast", ISP="AS7922"} 67.4%
fallback_rate{region="US-Midwest"} 2.1%
fallback_rate{region="Europe"} 1.9%

## Сетевая диагностика с edge-узла
$ mtr -P UDP/443 route-to-AS7922-customer
hop 5: (AS7922 transit edge) UDP packets: 0% loss [OK]
hop 6: (AS7922 DDoS scrubber, новое правило: 2026-04-15 14:00 UTC)
     UDP packets: 100% loss [BLOCKED]
hop 7+: unreachable

Пик HTTP/3-fallback появился для трафика одного ISP (AS7922, US-Northeast), но нигде больше. MTR показывает, что UDP доходит до хопа 5 без потерь. Где блок и какова вероятная причина?

Найди ошибку

Вывод curl -v для ошибочно настроенного HTTP/3-сервера

log
$ curl --http3-only -v https://api.example.com/health
* Trying 203.0.113.42:443...
* QUIC handshake fail: protocol violation: invalid initial packet
* Closing connection
curl: (35) QUIC handshake fail: protocol violation: invalid initial packet

$ curl -v https://api.example.com/health
* Connected to api.example.com (203.0.113.42) port 443
* ALPN: offers h2,http/1.1
* ALPN: server accepted h2
< HTTP/2 200 OK
< alt-svc: h3=":443"; ma=86400
< server: nginx/1.27.0
< x-quic-version: draft-29
< content-type: application/json
{"status":"ok"}

HTTP/3 явно падает с 'protocol violation: invalid initial packet', но сервер рекламирует h3 через Alt-Svc. В чём мискофигурация и как исправить?

Какой RFC?

Какой RFC определяет транспортный протокол QUIC (не сам HTTP/3, не TLS-over-QUIC)?

Спроектируй

Вы разворачиваете HTTP/3 для глобального API с 10k req/s из 50+ стран, ожидая, что 5–15% путей блокируют UDP/443. Спроектируйте стратегию rollout HTTP/3.

  • Часть корпоративных и операторских сетей тихо блокирует UDP/443.
  • Нельзя сломать существующих HTTP/1.1 и HTTP/2 клиентов.
  • Мобильные пользователи на сотовой связи — приоритетная цель для изоляции потерь HTTP/3.
  • SRE-команда должна обнаруживать инциденты блокировки UDP в течение 5 минут.
Вспомните перед уходом
  1. 01
    Объясните, почему QPACK существует отдельно от HPACK.
  2. 02
    Инженер говорит, что HTTP/3 всегда лучше HTTP/2 из-за потоков QUIC. Где изъян в рассуждении?
  3. 03
    Что такое коалесценция соединений и что её ломает?
Итог

Эксплуатация HTTP/3 в продакшне фундаментально зависит от надёжности UDP-пути и операционной наблюдаемости. Независимость потоков QUIC означает, что один потерянный пакет останавливает только потоки, чьи данные он нёс — но это требует пакетного отслеживания потерь QUIC (не байтовой модели TCP) и encoder/decoder control streams QPACK (не упорядоченной динамической таблицы HPACK). Управление перегрузкой QUIC работает в userspace — гибче, но CPU-интенсивнее. Переговоры о версии для HTTP/3 используют Alt-Svc или HTTPS/SVCB DNS и тихо откатываются на HTTP/2 при блокировке UDP/443 — ALPN-метрика распределения — сигнал. Коалесценция соединений экономит стоимость хендшейка для origin’ов, разделяющих один IP и SAN сертификата. 0-RTT экономит round-trip, но требует server-side anti-replay и должен быть ограничен идемпотентными методами.

Связанные уроки
встречается в5
Продолжить восхождение ↑HTTP дизайн: приоритеты, WebTransport и семантическая корректность
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources7
expand
  1. 01
  2. 02
  3. 03
  4. 04
  5. 05
  6. 06
  7. 07

Trademarks belong to their respective owners. Editorial reference only.