HTTP/2: streams и мультиплексирование
HTTP/2 сохраняет семантику HTTP, но заменяет текстовое HTTP/1.1 framing бинарными фреймами. Несколько логических streams делят одно TCP-соединение: HEADERS и DATA разных запросов могут чередоваться. Это убирает HOL blocking HTTP/1.1 между ответами, но не отменяет порядок доставки TCP.
Зачем это на интервью
Сильный ответ не сводится к «HTTP/2 быстрее». Он называет выигрыш — меньше соединений и независимые HTTP-стримы — и ограничения: packet loss на одном TCP connection, flow-control, CPU на TLS/HPACK, прокси и неверно настроенные лимиты.
Минимум для E4
- Отличать connection, stream, message и frame.
- Объяснять, что stream имеет идентификатор и состояние, а фрейм — единицу передачи.
- Знать назначение SETTINGS, HEADERS, DATA, WINDOW_UPDATE, RST_STREAM и GOAWAY.
- Понимать, что HTTP/2 требует TLS в браузерной практике, хотя протокол этого не делает обязательным.
Клиент и сервер обмениваются SETTINGS в начале соединения. MAX_CONCURRENT_STREAMS ограничивает одновременно активные streams, а flow-control window ограничивает объём DATA, который отправитель может послать до WINDOW_UPDATE. Это механизм защиты получателя от переполнения, а не rate limiting пользователя.
Углубление для E5/Senior
HPACK сжимает headers через статическую и динамическую таблицы. Динамическая таблица — состояние соединения, поэтому декодер обязан ограничивать размеры и применять настройки до обработки. Нельзя логировать или считать секреты безопасными лишь потому, что заголовок «сжат»: TLS защищает канал, но token всё равно может попасть в trace/metrics.
Мультиплексирование меняет форму перегрузки: один большой stream способен занимать flow-control window или доступную полосу, а потерянный TCP segment задержит последующие байты всех streams. Priority RFC 7540 исторически плохо интероперабельна; не стройте SLO на её предположениях. Для graceful drain сервер посылает GOAWAY с последним обработанным stream ID, клиент открывает новое соединение для более новых streams.
Ключевые понятия
- Frame — бинарный блок протокола; message — request/response; stream — двунаправленный логический канал.
- Multiplexing — interleaving фреймов разных streams в одном соединении.
- Flow control — кредитный механизм на DATA; он существует на stream и connection уровне.
- HPACK — сжатие HTTP headers со статической и динамической таблицами.
- GOAWAY — сигнал прекращения создания новых streams с возможностью дочистить уже принятые.
Типовые вопросы
- Что именно устраняет HTTP/2?
- Прикладную блокировку порядка ответов HTTP/1.1: маленький готовый ответ может идти между DATA другого stream.
- Почему loss всё ещё влияет на все streams?
- TCP доставляет байты в строгом порядке; потерянный сегмент останавливает выдачу последующих байтов приложению.
- Зачем нужен flow control?
- Чтобы получатель дозировал буферизацию DATA. Это не замена лимиту запросов или fairness между tenants.
- Когда использовать
RST_STREAM, а не закрывать connection?- Когда ошибка относится к одному запросу: отмена stream не должна обрывать здоровые соседние requests.
- Как безопасно перезапустить backend?
- Послать
GOAWAY, перестать принимать новые streams, дождаться in-flight до deadline и затем закрыть connection.
- Послать
- Почему header compression требует ограничений?
- Большие или специально подобранные headers расходуют CPU/память декодера; нужны лимиты полей, таблицы и размера списка headers.
Практика
- Снимите HTTP/2-сеанс через
curl --http2 -v; критерий: найдены negotiated protocol, stream IDs и переиспользование connection. - Отмените один долгий запрос контекстом; критерий: сервер освобождает работу этого stream, соседний запрос на том же connection завершается успешно.
- Проведите graceful shutdown HTTP/2-сервера; критерий: новые streams получают новое соединение, принятые завершаются или получают документированную deadline-ошибку.
Частые ошибки и ловушки
- Приписывать HTTP/2 устранение TCP HOL blocking.
- Считать
MAX_CONCURRENT_STREAMSглобальным rate limit или не учитывать его в client pool. - Закрывать всё соединение при отмене одного request.
- Не задавать max header list size и лимиты тела, надеясь только на HPACK.
Связанные темы
HTTP и Web · HTTP/1.1: соединения · HTTP/3 и QUIC · RPC и gRPC · Наблюдаемость
Источники
- RFC 9113, HTTP/2.
- RFC 7541, HPACK: Header Compression for HTTP/2.
- RFC 9110, HTTP Semantics.
- Go documentation:
net/httpHTTP/2 support andx/net/http2.