Расскажите об особенностях и ключевых преимуществах протокола HTTP/2.

Ответ

HTTP/2 — это вторая основная версия протокола HTTP, пришедшая на смену HTTP/1.1. Его главной целью было повышение производительности за счет решения ключевых проблем предшественника.

В отличие от текстового HTTP/1.1, HTTP/2 является бинарным протоколом. Это упрощает парсинг и делает его менее подверженным ошибкам.

Ключевые нововведения:

  • Мультиплексирование (Multiplexing): Позволяет одновременно отправлять несколько запросов и получать несколько ответов в рамках одного TCP-соединения. Это решает проблему "Head-of-line blocking" на уровне HTTP, когда медленный ответ блокировал все последующие.
  • Приоритизация потоков (Stream Prioritization): Клиент может указать браузеру, какие ресурсы важнее (например, сначала загрузить CSS, а потом изображения), что позволяет оптимизировать отрисовку страницы.
  • Сжатие заголовков (Header Compression, HPACK): Заголовки в HTTP/1.1 часто дублируются и передаются в текстовом виде. HPACK сжимает их, значительно уменьшая объем передаваемых метаданных.
  • Server Push: Сервер может отправлять ресурсы клиенту до того, как он их запросит. Например, вместе с index.html сервер может сразу отправить style.css и script.js, так как он предполагает, что они понадобятся клиенту.

Пример Server Push в Go:

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    // Проверяем, поддерживает ли клиент Server Push
    if pusher, ok := w.(http.Pusher); ok {
        // Отправляем CSS заранее, не дожидаясь запроса от клиента
        if err := pusher.Push("/static/style.css", nil); err != nil {
            log.Printf("Failed to push: %v", err)
        }
    }
    // Отдаем основную страницу
    fmt.Fprintln(w, "<html>...</html>")
})

Важное ограничение:

  • HTTP/2 не решает проблему Head-of-Line blocking на уровне TCP. Если один TCP-пакет теряется, все потоки внутри соединения ждут его переотправки. Эту проблему решает уже следующий протокол — HTTP/3, работающий поверх QUIC (UDP).