Gymterview
middle

Чем отличаются HTTP/1.1, HTTP/2 и HTTP/3?

HTTP/1.1, HTTP/2 и HTTP/3 — три поколения протокола HTTP, каждое из которых решает проблемы предыдущего: от текстового протокола с блокировкой до бинарного мультиплексированного протокола поверх QUIC.

Сравнительная таблица

Свойство HTTP/1.1 HTTP/2 HTTP/3
Год стандартизации 1997 2015 2022
Транспорт TCP TCP QUIC (поверх UDP)
Формат Текстовый Бинарный Бинарный
Мультиплексирование Нет (один запрос за раз на соединение) Да (множество потоков в одном TCP-соединении) Да (потоки независимы)
Head-of-line blocking На уровне HTTP и TCP Решено на уровне HTTP, но остаётся на уровне TCP Полностью решено
Сжатие заголовков Нет HPACK QPACK
Server Push Нет Да Да (редко используется)
Шифрование Опционально (HTTPS) Фактически обязательно Обязательно (встроено в QUIC)
Время установления соединения 1 RTT (TCP) + 2 RTT (TLS 1.2) 1 RTT (TCP) + 1 RTT (TLS 1.3) 1 RTT (QUIC + TLS 1.3), 0-RTT при повторном

HTTP/1.1

  • Один запрос за раз на одно TCP-соединение. Pipelining существует в спецификации, но на практике не работает из-за head-of-line blocking (ответы должны приходить в порядке запросов)
  • Для параллельности браузеры открывают 6–8 TCP-соединений к одному серверу
  • Заголовки передаются текстом, повторяются в каждом запросе (Cookie, User-Agent — десятки и сотни байт)
  • Оптимизации-«костыли»: keep-alive, конкатенация файлов, CSS-спрайты, domain sharding

HTTP/2

  • Бинарный протокол — данные передаются в виде фреймов (frames), что эффективнее парсинга текста
  • Мультиплексирование — множество запросов и ответов передаются одновременно по одному TCP-соединению, чередуясь фреймами. Не нужно ждать завершения предыдущего запроса
  • Сжатие заголовков (HPACK) — заголовки сжимаются и индексируются; повторяющиеся заголовки передаются как ссылки на индекс
  • Server Push — сервер может отправить ресурсы до того, как клиент их запросит (например, CSS к HTML-странице)
  • Проблема: head-of-line blocking на уровне TCP — если один TCP-пакет потерян, все потоки HTTP/2 ждут его повторной передачи, даже если потеря касается только одного потока

HTTP/3

  • Использует QUIC — транспортный протокол поверх UDP, разработанный Google
  • Каждый HTTP-поток в QUIC независим: потеря пакета одного потока не блокирует другие — head-of-line blocking полностью решён
  • Встроенное шифрование (TLS 1.3) — handshake QUIC и TLS происходят одновременно, что сокращает время установления соединения
  • 0-RTT — при повторном подключении к серверу данные могут отправляться сразу, без ожидания handshake
  • Миграция соединений — QUIC идентифицирует соединение по Connection ID, а не по IP:port, что позволяет сохранять соединение при смене сети (Wi-Fi → мобильная сеть)
  • Лучше работает при нестабильном соединении (мобильные сети, потери пакетов)

Эволюция решения проблемы HOL blocking

Пример
HTTP/1.1: Запрос 1 ──→ Ответ 1 ──→ Запрос 2 ──→ Ответ 2   (последовательно)

HTTP/2:   Запрос 1 ─┐                                       (мультиплекс, но
          Запрос 2 ─┤── один TCP-поток ──→ TCP потеря ──→    все ждут)
          Запрос 3 ─┘

HTTP/3:   Запрос 1 ─── QUIC поток 1 ──→ потеря ──→ ждёт только поток 1
          Запрос 2 ─── QUIC поток 2 ──→ OK        (независимо)
          Запрос 3 ─── QUIC поток 3 ──→ OK        (независимо)

Для Java-разработчика

  • java.net.http.HttpClient (Java 11+) поддерживает HTTP/1.1 и HTTP/2
  • Spring Boot (Tomcat, Jetty, Netty) поддерживает HTTP/2 с минимальной конфигурацией (server.http2.enabled=true)
  • Для HTTP/3 пока нужны сторонние библиотеки или reverse proxy (Nginx 1.25+, Caddy, HAProxy)
  • В микросервисной архитектуре HTTP/2 между сервисами (например, gRPC) даёт существенный прирост за счёт мультиплексирования

Вывод

HTTP/1.1 → HTTP/2 → HTTP/3 — это эволюция в сторону более быстрой, параллельной и устойчивой передачи данных. HTTP/2 решил проблему блокировки на уровне HTTP, HTTP/3 — на уровне транспорта. Для большинства Java-приложений HTTP/2 уже доступен из коробки; HTTP/3 приходит через reverse proxy.

На собеседовании: ключевой вопрос — что такое head-of-line blocking и как каждая версия его решает. Также полезно объяснить, почему HTTP/3 использует UDP (не потому что он «быстрее», а потому что TCP нельзя модифицировать в middlebox — маршрутизаторах и NAT — а QUIC реализует надёжность поверх UDP в user space).