Фото Wolfgang Rottmann, Unsplash.com
После почти пятилетних разработок протокол HTTP/3 наконец приближается к окончательному выпуску. Рассказываем, какие трудности могут возникнуть при развёртывании и тестировании HTTP/3 и как адаптировать к нему сайты и ресурсы.
Это третья и последняя часть серии о новых протоколах HTTP/3 и QUIC. Если, прочитав предыдущие две части об истории и основных концепциях и функциях производительности HTTP/3, вы решили, что новые протоколы срочно нужно внедрять (будем надеяться, что так вы и решили), здесь мы расскажем, как это сделать.
Начнём с того, что нужно изменить в страницах и ресурсах, чтобы оптимально использовать новые протоколы (это самая простая часть). Затем узнаем, как настроить серверы и клиенты (это сложно, если вы не используете CDN). Наконец, мы увидим, какие инструменты помогут оценить влияние новых протоколов на производительность (здесь пока всё совсем сложно).
Статьи серии:
-
Часть 1: история и ключевые концепции HTTP/3
Эта часть для тех, кто в целом мало что знает об HTTP/3 и протоколах. Здесь мы говорим о самых основах.
-
Часть 2: характеристики производительности HTTP/3
Тут мы углубимся в технические детали. Если с основами вы уже знакомы, начинайте со второй части.
-
Часть 3: развёртывание HTTP/3 на практике
Здесь описываются трудности, связанные с самостоятельным развёртыванием и тестированием HTTP/3. Мы поговорим, как нужно изменить веб-страницы и ресурсы и нужно ли вообще.
Изменения для страниц и ресурсов
Начнём с хороших новостей: если вы уже используете HTTP/2, скорее всего, при переходе на HTTP/3 менять страницы и ресурсы не придётся совсем. В первой и во второй части мы уже объясняли, что HTTP/3, по сути, это HTTP/2-over-QUIC, и на прикладном уровне две версии не отличаются друг от друга. Все изменения и оптимизации под HTTP/2 будут работать для HTTP/3 и наоборот.
А вот если вы всё ещё держитесь за HTTP/1.1, забыли о переходе на HTTP/2 или ничего не настраивали для HTTP/2, вы можете задаваться вопросом, что и как нужно изменить, для того, чтобы быть готовым к HTTP/3. Даже сегодня сложно найти хорошую статью со всеми подробностями. Как я уже говорил в первой части, сначала все были слишком оптимистично настроены по поводу использования HTTP/2, поэтому многие статьи содержат серьёзные ошибки и плохие советы. К сожалению, многие заблуждения никуда не делись, поэтому я и написал эту серию — чтобы с HTTP/3 такое не повторилось.
Лучше всего об HTTP/2 написано в книге HTTP/2 in Action, автор Barry Pollard. Но она платная, так что я расскажу здесь о самых важных моментах и об их связи с HTTP/3:
1. Одно соединение
Главное отличие HTTP/2 от HTTP/1.1 — одно TCP-соединение вместо 6–30 параллельных. Во второй части я упомянул, что одно соединение может быть таким же быстрым, как несколько, потому что из-за контроля перегрузок может потеряться больше пакетов или потери начнутся раньше (что сведёт на нет преимущества в скорости из-за их одновременного старта). HTTP/3 придерживается такого же подхода, но с протоколом QUIC вместо TCP. Сама по себе разница несущественная (разве что издержки на стороне сервера меньше), но с ней связано много других факторов.
2. Шардинг между серверами и объединение соединений
На практике было очень сложно перейти на одно соединение, потому что многие страницы были разделены между именами хостов и даже серверами (например,
img1.example.com
и img2.example.com
). Всё потому, что браузеры открывали не больше шести соединений для каждого имени хоста, так что если их было несколько, соединений могло быть больше. Без изменений HTTP/2 до сих пор открывал бы несколько соединений, мешая работать другим функциям, например, приоритизации (см. ниже).Так что всем советовали отменить шардинг между серверами и по максимуму собрать ресурсы на одном сервере. У HTTP/2 даже была функция объединения соединений, которая упрощала переход с HTTP/1.1, — connection coalescing. В общих чертах, если два имени хоста соответствуют одному IP сервера (через DNS) и используют аналогичный сертификат TLS, браузер может использовать одно соединение даже между двумя именами хостов.
На практике объединение соединений сложно правильно организовать, например, из-за некоторых хитрых проблем безопасности, связанных с CORS. Даже если всё настроить правильно, соединений все равно может оказаться два. Правда, это не всегда плохо. Во-первых, из-за плохо реализованных приоритизации и мультиплексирования (см. ниже) одно соединение может быть медленнее, чем два и больше. Во-вторых, если соединений слишком много, пакеты начнут теряться раньше из-за состязающихся контролеров перегрузок. Если их будет немного (но больше одного), можно найти баланс между перегрузкой и улучшенной производительностью, особенно в быстрых сетях. Так что, по-моему, немного шардинга (где-то 2–4 соединения) не повредит даже для HTTP/2. Фактически большинство современных HTTP/2 ресурсов имеют такие скорости прогрузки, потому что у них всё ещё есть дополнительные соединения или загрузки сторонних ресурсов в «критическом пути».
3. Объединение и встраивание ресурсов
В HTTP/1.1 мог быть только один активный ресурс на соединение, что приводило к блокировке начала очереди (head-of-line, HoL) на уровне HTTP. Соединений было всего 6–30, так что долгое время все практиковали объединение ресурсов в бандл (resource bundle). Даже сегодня есть подобные инструменты, например, Webpack. Кроме того, одни ресурсы часто встраивались в другие (например, критический CSS встраивался в HTML).
Соединение HTTP/2 мультиплексирует ресурсы, поэтому невыполненных запросов для файлов может быть гораздо больше — один запрос больше не занимает соединение (которых и так немного) целиком. Сначала все решили, что в HTTP/2 больше не нужно объединять и встраивать ресурсы. Считалось, что каждый подресурс можно кэшировать по отдельности, и не нужно снова загружать весь бандл, если один из ресурсов изменился. Это правда, но применимо к ограниченному набору ситуаций.
Например, можно понизить коэффициент сжатия, потому что сжатие эффективнее работает с большими объёмами. Кроме того, каждый запрос или файл связан с издержками, потому что должен обрабатываться браузером или сервером. У нескольких сотен маленьких файлов эти издержки будут гораздо больше, чем у нескольких больших файлов. В наших ранних тестах я заметил ухудшение примерно на 40 файлах. Сейчас это число, наверное, немного больше, но файловые запросы до сих пор обходятся не так дёшево, как все изначально ждали от HTTP/2. Наконец, если не встраивать ресурсы, это увеличивает задержку, потому что файлы нужно запрашивать. Более того, из-за проблем с приоритизацией и server push (см. ниже) лучше всё же встраивать критические CSS. Может быть, однажды технология Resource Bundles поможет в этом, но пока этот момент ещё не настал.
Всё это относится и к HTTP/3. Говорят, что QUIC лучше справляется со множеством маленьких файлов, потому что чем больше независимых параллельных потоков, тем больше пользы от удаления блокировки HoL (мы говорили об этом во второй части). Может быть, отчасти это правда, но мы уже видели, что это очень сложная проблема с большим числом переменных. Не думаю, что преимущества перевесят остальные затраты, но нужно подробно изучить вопрос. (Просто мысли вслух: файлы могут быть такого размера, чтобы точно вписываться в один пакет QUIC, и тогда блокировка HoL вообще не будет нас беспокоить. Принимаю роялти от стартапа, который реализует такой бандлер.;))
4. Приоритизация
Чтобы загрузить несколько файлов по одному соединению, их нужно как-то мультиплексировать. Как мы говорили во второй части, в HTTP/2 это мультиплексирование управляется через систему приоритизации. Ещё и поэтому важно, чтобы в одном соединении было запрошено как можно больше ресурсов, — так их можно правильно приоритизировать. Мы видели, что система была очень сложной, часто ее неправильно использовали и реализовывали на практике (см. изображение ниже). Это означало, что некоторые рекомендации для HTTP/2 (объединение ресурсов, раз запросы все равно дешёвые, и отказ от шардинга, чтобы оптимально использовать одно соединение) в реальности не давали ожидаемых преимуществ.
В плохо реализованных стеках HTTP/2 ресурсы с высоким приоритетом (два нижних) загружаются после остальных ресурсов, у которых приоритет ниже. (Источник изображения: Andy Davies) (исходное изображение)
К сожалению, обычный веб-разработчик мало что может с этим сделать, потому что это проблема на стороне браузеров и серверов. Но вы хотя бы можете не использовать слишком много отдельных файлов (так будет сложнее расставить приоритеты) и применять шардинг, пусть и ограниченно. Ещё можно использовать методы расстановки приоритетов, например lazy loading,
async
и defer
в JavaScript, и resource hints, например preload
. Все эти механизмы меняют приоритеты ресурсов, чтобы они отправлялись раньше или позже. Но и эти механизмы не без греха. Не думайте, что можно просто назначить preload
группе ресурсов и они сразу станут загружаться быстрее: если у всех ресурсов высокий приоритет, значит, у всех ресурсов одинаковый приоритет! Можно легко взять и отложить загрузку действительно критичных ресурсов, просто используя preload.Во второй части мы видели, как сильно изменилась система приоритизации в HTTP/3. Мы надеемся, что багов и проблем на практике станет меньше, но пока ни в чём не уверены, потому что мало серверов и клиентов HTTP/3 полностью реализовали эту систему. В любом случае, фундаментальные концепции приоритизации не изменятся. Вы всё ещё не сможете использовать такие механизмы, как preload, не понимая, что происходит внутри, потому что можно случайно неверно расставить приоритеты.
5. Server push
Server push позволяет отправлять ответ, не дожидаясь запроса от клиента. В теории звучит интересно, и эту функцию можно использовать вместо встраивания. Во второй части мы уже говорили, что push сложно использовать правильно из-за проблем с контролем перегрузок, кешированием, приоритизацией и буферизацией. В целом, лучше не использовать server push для загрузки веб-страниц, разве что вы точно знаете, что делаете. Но и тогда большого преимущества вы не получите. Я уверен, что server push может найти применение в (REST) API, чтобы пушить подресурсы, на которые ссылается ответ (JSON), в заранее подготовленном соединении. Это относится как к HTTP/2, так и к HTTP/3.
Думаю, это также относится к возобновлению сеанса TLS и 0-RTT для TCP + TLS или QUIC. Как мы видели во второй части, 0-RTT похож на server push в том, что тоже пытается ускорить начальные этапы загрузки страницы. Но пока обе функции дают очень ограниченные преимущества (особенно в QUIC, где это связано с безопасностью). Чтобы получить пользу, нужно будет тщательно все настраивать на нижнем уровне. Поверить не могу, что раньше мне просто не терпелось объединить server push с 0-RTT.
Что всё это значит?
Можно сформулировать общее правило: применяйте большинство обычных рекомендаций для HTTP/2, но не переусердствуйте.
Вот, например, советы, которые подойдут для HTTP/2 и HTTP/3:
- Разделяйте ресурсы по 1–3 соединениям для критического пути (если только большинство ваших пользователей не находятся в сетях с маленькой полосой пропускания), применяя preconnect и dns-prefetch, где нужно.
- Объединяйте подресурсы по логическому принципу — по пути, функции или частоте изменений. 5–10 JavaScript и 5–10 ресурсов CSS на страницу — это хороший вариант. Встраивать критические CSS по-прежнему может быть полезно.
- Используйте сложные функции, например preload, без фанатизма.
- Используйте сервер, который корректно поддерживает приоритизацию HTTP/2. Для HTTP/2 рекомендую H2O. Apache и NGINX тоже ничего (хотя могло быть и лучше), а Node.js не особо подходит для HTTP/2. По HTTP/3 пока мало сведений (см. ниже).
- Убедитесь, что для веб-сервера HTTP/2 включен TLS 1.3.
Как видите, оптимизировать страницы для HTTP/3 (и HTTP/2) не просто, но и не слишком сложно. Сложнее будет правильно настроить серверы, клиенты и инструменты для HTTP/3.
Серверы и сети
Наверное, вы уже понимаете, что QUIC и HTTP/3 — довольно сложные протоколы. Чтобы реализовать их с нуля, придётся прочитать (и понять!) сотни страниц в семи и более документах. К счастью, сразу несколько компаний уже пять лет работают над опенсорс-реализациями QUIC и HTTP/3, так что у нас есть несколько зрелых и стабильных вариантов на выбор.
Лучшие из них:
Язык |
Реализация |
Python |
aioquic |
Go |
quic-go |
Rust |
quiche (Cloudflare), Quinn, Neqo (Mozilla) |
C и C++ |
mvfst (Facebook), MsQuic, (Microsoft), (Google), ngtcp2, LSQUIC (Litespeed), picoquic, quicly (Fastly) |
Многие (или даже большинство) реализаций, в основном, решают вопросы HTTP/3 и QUIC, и это не полноценные веб-серверы. Если говорить об обычных серверах (вроде NGINX, Apache, Node.js), тут всё идёт не так быстро, и причин тому несколько. Во-первых, мало кто из их разработчиков участвовал в создании HTTP/3 с самого начала, и сейчас приходится нагонять. Многие просто берут какую-нибудь реализацию из списка выше и используют её как библиотеку, но даже интеграция требует много усилий.
Во-вторых, многие серверы используют сторонние библиотеки TLS, например OpenSSL, потому что протокол TLS очень сложный и должен быть хорошо защищён, так что лучше брать уже испытанные решения. Хотя QUIC интегрирован с TLS 1.3, он использует этот протокол совсем не так, как TCP. Это значит, что библиотеки TLS должны предоставлять API специально для QUIC, а их разработчики с этим не спешат. Особенно всё сложно с OpenSSL, которая откладывает поддержку QUIC, но при этом используется многими серверами. Akamai даже начали собственный форк OpenSSL для QUIC и назвали его quictls. Есть другие варианты и обходные пути, но поддержка TLS 1.3 для QUIC всё ещё мешает реализовать протокол на многих серверах, и в ближайшем будущем ничего не изменится.
Неполный список полноценных веб-серверов, которые можно использовать без дополнительной настройки, с указанием того, поддерживают ли они HTTP/3:
-
Apache
Пока про поддержку ничего не известно. Никаких объявлений не было. Скорее всего, нужен OpenSSL. (Но есть реализация Apache Traffic Server.)
-
NGINX
Это кастомная реализация, относительно новая и пока очень экспериментальная. Слияние с основной веткой NGINX ожидается к концу 2021 года. Существует патч для запуска библиотеки Cloudflare quiche на NGINX, и, пожалуй, это пока что более стабильный вариант.
-
Node.js
Использует библиотеку ngtcp2, развитие которой блокируется развитием OpenSSL, хотя они планируют перейти на форк QUIC-TLS, чтобы поскорее хоть что-то наладить.
-
IIS
Пока про поддержку ничего не известно, никаких объявлений. Скорее всего, будет использоваться библиотека MsQuic.
-
Hypercorn
Интегрирует aioquic, экспериментальная поддержка.
-
Caddy
Использует quic-go, полная поддержка.
-
H2O
Использует quicly, полная поддержка.
-
Litespeed
Использует LSQUIC, полная поддержка.
Важные примечания:
- Даже «полная поддержка» предоставляется «как есть» и не означает готовность для продакшена. Например, многие реализации еще не полностью поддерживают миграцию соединения, 0-RTT, server push или приоритизацию в HTTP/3.
- Серверы, которых нет в списке, например Tomcat, пока, насколько мне известно, не делали никаких объявлений.
- Среди серверов из списка только Litespeed, патч Cloudflare для NGINX и H2O разрабатываются теми, кто активно участвовал в стандартизации QUIC и HTTP/3, так что пока, пожалуй, это лучшие варианты.
Как видите, вариантов немного, но что-то выбрать уже можно. Мало просто запустить сервер — куда сложнее настроить его и всю остальную сеть.
Конфигурация сети
Как мы говорили в первой части, QUIC работает поверх UDP, чтобы его было проще развёртывать, потому что большинство сетевых устройств понимает UDP. К сожалению, UDP разрешен не везде. Его часто используют для атак, и он не очень-то нужен в повседневной работе, кроме как для DNS, так что многие корпоративные сети и файрволы почти полностью его блокируют. Скорее всего, UDP нужно будет явно разрешить для входящего и исходящего трафика HTTP/3-серверов. QUIC может использовать любой порт UDP, но обычно это порт 443 (которые используется и для HTTPS-over-TCP).
Многие сетевые администраторы не захотят разрешать весь UDP-трафик, только QUIC-over-UDP. Проблема в том, что QUIC почти полностью зашифрован, включая метаданные, допустим номера пакетов, а также, например, сигналы о закрытии соединения. Для TCP файрволы активно отслеживают все метаданные, чтобы исключить неожиданное поведение. (До пакетов с данными выполнено полное рукопожатие? Пакеты соответствуют ожидаемым паттернам? Сколько соединений открыто?) В первой части мы говорили, что это как раз одна из причин, которые мешают развитию TCP. Но из-за шифрования QUIC файрволы не могут отслеживать почти ничего, а то, что могут, представляет сложности.
Сейчас многие вендоры файрволов рекомендуют блокировать QUIC, пока они не обновят софт. И даже после этого компании будут неохотно разрешать QUIC, потому что файрвол будет поддерживать гораздо меньше функций QUIC, чем дает TCP.
Функция миграции соединений только все усложняет. Мы видели, что она продолжает соединение по новому IP-адресу без дополнительных рукопожатий, с помощью идентификаторов соединений (CID). Файрвол же видит новое соединение без рукопожатия и подозревает, что это злоумышленник отправляет вредоносный трафик. Файрвол не может использовать QUIC CID, потому что из соображений приватности они время от времени меняются. Поэтому нужно будет, чтобы серверы сообщали файрволу ожидаемые CID, но пока таких механизмов не существует.
Те же опасения относятся к балансировщикам нагрузки в масштабных развёртываниях, где входящие соединения распределяются по большому числу бэкенд-серверов. Трафик для одного соединения нужно будет направить на тот же бэкенд-сервер, потому что остальные не будут знать, что с ним делать. В TCP это можно сделать с помощью четырёх параметров, которые никогда не меняются. Если использовать миграцию соединения в QUIC, это уже не поможет. Повторю: серверы и балансировщики нагрузки должны как-то договориться о выборе CID, чтобы разрешить детерминированную маршрутизацию. В отличие от конфигурации файрвола, здесь уже есть предложение по настройке (хотя оно пока мало где реализовано).
Наконец, есть и другие, более общие, соображения по безопасности, в основном, связанные с 0-RTT и DDoS-атаками. Во второй части мы видели, что в QUIC эти проблемы уже активно решаются, но в идеале не помешало бы ещё несколько линий обороны в сети. Например, прокси- или граничные серверы могут не пропускать некоторые запросы 0-RTT к бэкендам, чтобы не допустить атаки повторением (replay attack). Чтобы защититься от атак отражением (reflection attack) или DDoS-атак, которые отправляют первый пакет рукопожатия, а потом перестают отвечать (так называемый SYN-флуд в TCP), QUIC включает функцию повторных попыток. Это позволяет серверу убедиться в добросовестности клиента, не храня никакое состояние (эквивалент TCP SYN cookie). Процесс повторных попыток, конечно, лучше разместить где-нибудь до бэкенд-сервера. На балансировщике нагрузки, например. И снова для этого нужна дополнительная конфигурация и настройка коммуникаций.
Это только самые заметные проблемы, которые возникнут у сетевых и системных администраторов с QUIC и HTTP/3. Есть и другие, и я рассказывал о некоторых. Эти проблемы и частичные решения обсуждаются в двух отдельных документах (здесь и здесь) для QUIC RFC.
Что всё это значит?
HTTP/3 и QUIC — это сложные протоколы, использующие разные внутренние механизмы. Не все из них готовы на сто процентов, но у вас уже есть несколько вариантов развёртывания новых протоколов на бэкенде. Пройдёт несколько месяцев или даже лет, прежде чем основные серверы и базовые библиотеки (например, OpenSSL), будут обновлены.
И даже тогда в масштабных проектах сложно будет настроить серверы и другие сетевые устройства, чтобы новые протоколы можно было использовать безопасно и эффективно. Понадобится хорошая команда DevOps.
Особенно на начальных этапах будет лучше, если настройкой и конфигурированием протоколов за вас займется крупная хостинговая компания или CDN. Как мы говорили во второй части, именно здесь QUIC лучше всего проявит себя, а использование CDN позволяет серьёзно оптимизировать производительность. Лично я рекомендую Cloudflare или Fastly, потому что они активно участвуют в процессе стандартизации и смогут предложить самые продвинутые и продуманные реализации.
Клиенты и обнаружение QUIC
До сих пор мы говорили о поддержке новых протоколов на стороне сервера и в сети, но на стороне клиента тоже не всё так просто.
Начнем с хорошей новости: большинство браузеров уже поддерживают HTTP/3, пусть и в экспериментальном режиме. Вот как обстоят дела на момент написания статьи (см. также caniuse.com):
Браузеры активно поддерживают HTTP/3. (Источник: caniuse.com) (исходное изображение)
-
Google Chrome (version 91+): включено по умолчанию.
-
Mozilla Firefox (version 89+): включено по умолчанию.
-
Microsoft Edge (version 90+): включено по умолчанию (использует Chromium).
-
Opera (version 77+): включено по умолчанию (использует Chromium).
-
Apple Safari (version 14): включается вручную. Будет включено по умолчанию в версии 15, которая сейчас на стадии technology preview.
-
Другие браузеры: пока ничего неизвестно (хотя браузеры на Chromium, например Brave, в теории тоже могут поддерживать протокол).
Важные примечания:
- Большинство браузеров распространяют обновления постепенно, так что не все пользователи получат поддержку HTTP/3 по умолчанию с самого начала. Это делается для того, чтобы один пропущенный баг не повлиял сразу на всех пользователей и чтобы не перегрузить сервера обновлений. Есть небольшая вероятность, что даже в последних версиях браузера вы не получите HTTP/3 по умолчанию и придётся включать его вручную.
- Как и в случае с серверами, поддержка HTTP/3 не означает, что все функции реализованы или используются. Например, 0-RTT, миграция соединения, server push, динамическое сжатие заголовков QPACK и приоритизация HTTP/3 могут пока отсутствовать, использоваться осторожно или иметь неоптимальную конфигурацию.
- Если вы хотите использовать HTTP/3 на клиенте не в браузере (например, в нативном приложении), нужно интегрировать одну из библиотек из списка выше или использовать cURL. Apple скоро предоставит нативную поддержку HTTP/3 и QUIC во встроенных сетевых библиотеках на macOS и iOS, а Microsoft добавляет QUIC в ядро Windows и окружение .NET, но другие системы, например Android, пока не объявили о подобной поддержке.
ALT-SVC
Даже если у вас есть сервер, совместимый с HTTP/3, и обновлённый браузер, это не значит, что HTTP/3 будет работать стабильно. Чтобы понять причину, представьте себя на месте браузера. Пользователь просит вас открыть
example.com
(сайт, где вы раньше никогда не были), и вы используете DNS, чтобы преобразовать его в IP-адрес. Вы отправляете один или несколько пакетов рукопожатия QUIC на этот IP. Тут может возникнуть сразу несколько проблем:- Сервер не поддерживает QUIC.
- Одна из промежуточных сетей или файрволов полностью блокирует QUIC и/или UDP.
- Пакеты рукопожатия могут потеряться при передаче.
Как узнать, что именно случилось? Во всех трёх случаях вы просто не получите ответ на рукопожатие. Вы ждёте и надеетесь, что ответ придет. Когда время ожидания истечет, вы решите, что с HTTP/3 проблема. Тогда вы пытаетесь открыть TCP-соединение с сервером в надежде, что хотя бы HTTP/2 или HTTP/1.1 сработают.
Такой подход приводит к серьёзным задержкам, и особенно это будет проявляться в первые несколько лет, пока многие серверы и сети ещё не поддерживают QUIC. Простое, но наивное решение — открыть сразу два соединения (QUIC и TCP) и использовать то, по которому быстрее придёт ответ. Такой метод называется гонкой соединений, или happy eyeballs. Это возможно, но издержки будут большими. Даже если проигравшее соединение почти сразу закрывается, оно потребляет какое-то количество памяти и процессорных ресурсов на клиенте и сервере (особенно при использовании TLS). Есть и другие проблемы, связанные с IPv4 и IPv6 и атаками повторением (подробнее об этом я рассказываю в своем выступлении).
Так что браузеры предпочтут не рисковать и будут пытаться использовать QUIC, только если известно, что сервер поддерживает протокол. Если браузер впервые связывается с сервером, он будет использовать только HTTP/2 или HTTP/1.1 по TCP-соединению. Сервер может сообщить браузеру, что поддерживает HTTP/3, чтобы его можно было использовать для последующих соединений. Для этого в ответе, который отправляется по HTTP/2 или HTTP/1.1, задается специальный HTTP-заголовок. Заголовок называется Alt-Svc, что расшифровывается как alternative services (альтернативные сервисы). С помощью Alt-Svc можно сообщить браузеру, что определённый сервис доступен через другой сервер (IP и/или порт), а ещё он может указывать на альтернативные протоколы. См. рисунок 1.
Рис. 1: Facebook использует заголовок Alt-Svc, чтобы сообщить браузеру, что он доступен через HTTP/3 на порте UDP 443 (действует в течение 3600 с). Пока протокол называется h3-29 или h3-27 (29-я и 27-я черновые версии HTTP/3), но скоро останется только h3 (некоторые серверы, например, google.com, уже используют h3). (исходное изображение)
Получив заголовок Alt-Svc и узнав о поддержке HTTP/3, браузер кэширует его и с тех пор пытается установить QUIC-соединение. Некоторые клиенты делают это сразу (прямо во время начальной загрузки страницы, см. ниже), другие сначала ждут, пока закроются существующие TCP-соединения. Это означает, что браузер будет использовать HTTP/3 только после того, как уже загрузил хотя бы несколько ресурсов по HTTP/2 или HTTP/1.1. И даже тогда не всё идет гладко. Браузер уже знает, что сервер поддерживает HTTP/3, но про промежуточные сети ему ничего не известно. Так что на практике гонка соединений все ещё нужна. Придётся использовать HTTP/2, если рукопожатие QUIC застряло где-то в сети. Если QUIC-соединение не устанавливается несколько раз подряд, некоторые браузеры на какое-то время помещают кэшированную запись Alt-Svc в чёрный список и не пытаются использовать HTTP/3. Можно вручную очистить кэш браузера, если что-то идёт не так, чтобы удалить привязки Alt-Svc. Наконец, Alt-Svc, как оказалось, может представлять серьёзные риски для безопасности. Поэтому некоторые браузеры накладывают дополнительные ограничения, например, на доступные порты (в Chrome серверы HTTP/2 и HTTP/3 должны оба находиться либо ниже порта 1024 либо на порте 1024 и выше, иначе Alt-Svc будет игнорироваться). Логика у браузеров очень сильно различается, так что добиться стабильности HTTP/3-соединений сложно. Это затрудняет и тестирование новых площадок.
Работы по улучшению двухэтапного процесса Alt-Svc уже ведутся. Есть идея использовать новые записи DNS, SVCB и HTTPS, которые содержат примерно ту же информацию, что и Alt-Svc. С ними клиент может узнать, что сервер поддерживает HTTP/3, ещё на этапе разрешения DNS, а значит можно попробовать QUIC с первой загрузки страницы, не пытаясь сначала использовать HTTP/2 или HTTP/1.1. Больше об этом и об Alt-Svc см. в главе прошлогоднего Web Almanac об HTTP/2.
Как видите, Alt-Svc и обнаружение HTTP/3 добавляет сложности к и без того непростому развёртыванию сервера QUIC, потому что:
- Сервер HTTP/3 всегда нужно развёртывать рядом с сервером HTTP/2 и/или HTTP/1.1.
- Нужно настроить серверы HTTP/2 и HTTP/1.1 так, чтобы они задавали корректные заголовки Alt-Svc в ответах.
В продакшене это ещё можно настроить (например, один инстанс Apache или NGINX, скорее всего, будет поддерживать все три варианта HTTP одновременно), но в локальном тестовом окружении это будет очень хлопотно (лично я забываю добавлять заголовки Alt-Svc или допускаю ошибки в них). Проблема усугубляется тем, что в браузере сейчас недостаёт логов ошибок и индикаторов DevTools, то есть будет сложно понять, что именно пошло не так.
Другие проблемы
И это, к сожалению, не все сложности локального тестирования: Chrome очень затрудняет использование самоподписанных TLS-сертификатов для QUIC. Дело в том, что неофициальные TLS-сертификаты часто используются компаниями для дешифровки TLS-трафика сотрудников (чтобы файрволы, например, могли сканировать зашифрованный трафик). Если компании попытаются провернуть это с QUIC, мы опять получим кастомные реализации промежуточных устройств, которые строят собственные предположения о протоколе. Это может помешать поддержке протокола в будущем, а именно этого мы и пытались избежать, когда так старательно шифровали QUIC. У Chrome свой подход: если вы не используете официальный TLS-сертификат (подписанный центром сертификации или корневым сертификатом, которому Chrome доверяет, например Let’s Encrypt), то и QUIC вам использовать нельзя. К сожалению, это распространяется и на самоподписанные сертификаты, часто используемые для локальных тестовых окружений.
Можно обойти эту проблему с помощью навороченных флагов командной строки (потому что обычный --ignore-certificate-errors пока не работает для QUIC), используя сертификаты для каждого разработчика (хотя настраивать их долго) или установив реальный сертификат на ПК разработки (но это вряд ли подойдёт большим командам, потому что придётся предоставить закрытый ключ сертификата каждому разработчику). Наконец, мы можем установить кастомный корневой сертификат, но придется обойти флаги --origin-to-force-quic-on и --ignore-certificate-errors-spki-list при запуске Chrome (см. ниже). К счастью, сейчас такие строгие требования есть только в Chrome. Будем надеяться, его разработчики со временем передумают.
Если у вас возникают проблемы с настройкой QUIC в браузере, сначала проверьте их с помощью, например, cURL. cURL превосходно поддерживает HTTP/3 (можно даже выбирать из двух разных базовых библиотек), и с ним проще наблюдать за логикой кэширования Alt-Svc.
Что всё это значит?
Кроме сложностей с настройкой HTTP/3 и QUIC на стороне сервера, есть еще проблемы с согласованным использованием новых протоколов в браузерах. Они связаны с двухэтапным процессом обнаружения с HTTP-заголовком Alt-Svc и тем фактом, что HTTP/2-соединения нельзя просто проапгрейдить до HTTP/3, потому что последний использует UDP.
Даже если сервер поддерживает HTTP/3, клиенты (и владельцы сайтов!) ещё должны учитывать промежуточные сети, которые могут блокировать трафик UDP и/или QUIC. Поэтому HTTP/3 никогда полностью не заменит HTTP/2. На практике хорошо настроенная система HTTP/2 нужна будет при самом первом посещении и для клиентов в сетях, которые запрещают UDP. К счастью, и мы уже говорили об этом, страницы не придётся особо адаптировать под HTTP/3, так что хотя бы этой проблемы у нас не будет.
Зато проблемой может стать тестирование и проверка правильной конфигурации и ожидаемого использования протоколов. Это относится и к продакшену, но особенно к локальным развёртываниям. Я думаю, что большинство людей продолжат использовать серверы разработки с HTTP/2 (или даже HTTP/1.1) и перейдут на HTTP/3 только на более позднем этапе. И даже тогда тестировать производительность протокола с помощью инструментов текущего поколения будет сложно.
Инструменты и тестирование
Как и в случае с серверами, производители самых популярных инструментов тестирования веб-производительности не уследили за HTTP/3 с самого начала. В итоге на июль 2021 года у нас мало инструментов с поддержкой нового протокола, и даже эта поддержка неполная.
Google Lighthouse
Начнём с Google Lighthouse. В целом это превосходный инструмент тестирования веб-производительности, но мне всегда недоставало средств именно для протоколов. Проблема в том, что он симулирует медленные сети не очень правдоподобно (как и Chrome DevTools). Это удобный инструмент и обычно его достаточно, чтобы получить представление о медленной сети, но для тестирования различий низкоуровневых протоколов он мало что даёт. У браузера нет прямого доступа к стеку TCP, так что он загружает страницу по обычной сети, а потом искусственно задерживает передачу данных в логику браузера. То есть, например, Lighthouse симулирует только задержку и полосу пропускания, но не потерю пакетов (а мы уже видели, что это одно из главных различий между HTTP/3 и HTTP/2). Также Lighthouse использует продуманную модель симуляции, чтобы примерно оценить реальное влияние сети, потому что, допустим, Google Chrome использует сложную логику, чтобы корректировать некоторые аспекты загрузки страницы при обнаружении медленной сети. Эта модель, насколько я знаю (см. здесь и здесь) пока не адаптирована для IETF QUIC или HTTP/3. Так что если использовать Lighthouse только для сравнения производительности HTTP/2 и HTTP/3, можно получить ошибочные или слишком упрощённые результаты, по которым вы сделаете неверные выводы о возможностях HTTP/3 на практике. Можно надеяться, что в будущем инструмент будет усовершенствован, потому что у браузера есть полный доступ к стеку QUIC, так что Lighthouse может серьёзно улучшить симуляции (и даже учитывать потери пакетов!). Сейчас с помощью Lighthouse в теории можно тестировать загрузку страниц по HTTP/3, но я не рекомендую так делать.
Webpagetest
Ещё есть WebPageTest. Это отличный проект, который позволяет загружать страницы по реальным сетям с реальных устройств по всему миру и добавлять симуляцию на уровне пакетов, чтобы рассматривать сценарии с потерей пакетов. Поэтому WebPageTest, в принципе, может стать лучшим инструментом для сравнения производительности HTTP/2 и HTTP/3. Правда, хоть он и может уже загружать страницы по новому протоколу, HTTP/3 пока не полностью интегрирован в инструменты и визуализации. Например, сейчас нельзя просто принудительно загружать страницы по QUIC, чтобы посмотреть, как используется Alt-Svc, или изучить детали о рукопожатиях QUIC. В некоторых случаях сложно даже посмотреть, что использовал ответ — HTTP/3 или HTTP/2. И всё же у меня получилось с помощью WebPageTest потестировать, как это работает на facebook.com, и увидеть HTTP/3 в действии.
Сначала я запустил дефолтный тест для facebook.com, включив repeat view (повторный просмотр). Как я объяснял выше, первая загрузка страницы должна была использовать HTTP/2, а в заголовке ответа мы получили бы Alt-Svc. Поэтому при повторном просмотре должен был использоваться HTTP/3 с самого начала. В Firefox version 89 это более-менее происходит. Но если посмотреть на отдельные ответы, видно, что Firefox переключается на HTTP/3 уже при первой загрузке страницы! На рисунке 2 показано, что это происходит с 20-го ресурса. Это значит, что Firefox устанавливает новое QUIC-соединение, как только видит заголовок Alt-Svc, и переходит на него при первой возможности. Если прокрутить до соединений, видно, что Firefox даже открыл два QUIC-соединения: одно для доверенных CORS-запросов и одно для запросов без CORS. Это ожидаемо, ведь, как мы уже говорили, даже для HTTP/2 и HTTP/3 браузеры открывают несколько соединений из соображений безопасности. Поскольку WebPageTest не дает дополнительной информации, сложно проверить эту гипотезу, не просмотрев данные вручную. Если смотреть на второе посещение, первый же запрос использует HTTP/3, как и ожидалось.
Рис. 2: Firefox переходит на HTTP/3 на половине первой загрузки страницы. (исходное изображение)
У <a href=«www.webpagetest.org/result/210420_AiDcP0_6aeaac212f59298cf834ad30b4ec72e6»
>Chrome мы видим что-то похожее, хотя он меняет соединение на 10-м ресурсе, гораздо раньше, чем Firefox. Только непонятно, когда он это делает — при первой возможности или когда потребовалось новое соединение (например, для запросов с другими учётными данными), потому что, в отличие от Firefox, мы не видим несколько QUIC-соединений. Для повторного просмотра происходит что-то странное. Ни с того ни с сего Chrome начинает с HTTP/2 и переходит на HTTP/3 только после нескольких запросов. Я провел несколько тестов с другими страницами (например, вот, вот и вот) и убедился, что это для него нормальное поведение. Причин может быть несколько. Например, у Chrome такая политика, Chrome провел гонку между TCP и QUIC, и TCP сначала победил, или кэш Alt-Svc от первого просмотра почему-то не использовался. Сейчас, к сожалению, очень сложно определить, в чём проблема и можно ли ее исправить.
Ещё одно интересное наблюдение: соединения объединяются. Выше мы говорили, что HTTP/2 и HTTP/3 могут повторно использовать соединения даже при изменении имён хостов, чтобы избежать проблем шардинга. Но на рисунке 3 видно, что при этой загрузке ресурсов Facebook соединения объединялись при использовании HTTP/3 для facebook.com и fbcdn.net, но с HTTP/2 такого не было (Chrome открыл ещё одно соединение для второго домена). Думаю, это баг на WebPageTest, потому что у facebook.com и fbcnd.net разные IP и объединить их нельзя.
Ещё на рисунке видно, что на схеме WebPageTest не отображается кое-какая важная информация из рукопожатия QUIC.
Рис. 3: Кажется, Chrome объединяет соединения Facebook по HTTP/3, но не по HTTP/2. (исходное изображение)
Примечание. Как видите, полноценно оценить HTTP/3 сложно. К счастью, особенно для Chrome, мы добавили дополнительные варианты, с помощью которых можно тестировать QUIC и HTTP/3, в виде параметров командной строки.
В нижней части вкладки Chromium на WebPageTest я использовал следующие параметры:
--enable-quic --quic-version=h3-29 --origin-to-force-quic-on=www.facebook.com:443,static.xx.fbcdn.net:443
Результаты теста показывают, что так мы действительно начинаем с QUIC-соединения даже при первом просмотре, не используя Alt-Svc. Вы, наверное, заметили, что мне пришлось указать два имени хоста в --origin-to-force-quic-on. Если указать одно, Chrome сначала открывает для fbcnd.net HTTP/2-соединение, даже при повторном просмотре. Чтобы все получилось, придётся вручную указать все источники QUIC!
Эти примеры показывают, как сложно разобраться в использовании браузерами HTTP/3 на практике. Они даже переходят на новый протокол при начальной загрузке страницы, отключая HTTP/2 при первой возможности или когда потребуется новое соединение. Поэтому сложно не только загрузиться исключительно по HTTP/3, но но и только по HTTP/2, если поддерживаются оба протокола! WebPageTest пока показывает мало метаданных для HTTP/3 и QUIC, поэтому сложно понять, что происходит. Нельзя воспринимать буквально то, что мы видим в инструментах и на графиках.
Если вы используете WebPageTest, тщательно проверьте результаты, чтобы узнать, какие протоколы на самом деле использовались. Думаю, пока слишком рано по-настоящему тестировать производительность HTTP/3 (и особенно сравнивать его с HTTP/2). Плюс не все серверы и клиенты пока реализовали все возможности протокола. В WebPageTest нельзя посмотреть, использовались ли продвинутые функции, вроде 0-RTT, так что непонятно, что мы на самом деле измеряем. Особенно это касается приоритизации HTTP/3, которая пока не реализована как надо во всех браузерах, да и многие серверы пока полноценно не поддерживают её. Приоритизация значительно влияет на веб-производительность, так что некорректно сравнивать HTTP/3 с HTTP/2, не убедившись что всё работает правильно (в обоих протоколах!). Это всего один аспект, и мое исследование показывает, что между реализациями QUIC могут быть очень большие отличия. Если вы захотите сами провести сравнение (или будете читать статьи на эту тему), вы должны быть на 100% уверены в том, что на самом деле происходит.
Многие другие инструменты, вроде потрясающего HTTP Archive, часто основаны на WebPageTest или Lighthouse (или используют аналогичные методы), так что, думаю, мои комментарии подойдут для большинства средств тестирования веб-производительности. Даже если вендор объявляет, что вскоре будет поддерживать HTTP/3, я бы относился к этому насторожено и всё тщательно проверял. У некоторых инструментов всё совсем плохо, например, Google PageSpeed Insights только в этом году стал поддерживать HTTP/2, так что HTTP/3 я бы в ближайшее время не ждал.
Wireshark, qlog and qvis
Пока сложно проанализировать поведение HTTP/3 с помощью Lighthouse или WebPageTest. К счастью, есть более специализированные инструменты. Во-первых, это, конечно, Wireshark, который хорошо работает с QUIC и даже экспериментально анализирует HTTP/3. Он позволяет наблюдать за тем, какие пакеты QUIC и HTTP/3 проходят по сети. Чтобы всё работало, нужно получить ключи расшифровки TLS для конкретного соединения, и в большинстве реализаций (включая Chrome и Firefox) их можно извлечь с помощью переменной среды SSLKEYLOGFILE. Эти данные интересно изучить в некоторых сценариях, но чтобы по-настоящему разобраться в происходящем, особенно для долговременных соединений, придется много настраивать вручную и очень хорошо понимать, как устроены протоколы.
К счастью, есть другой вариант — qlog и qvis. qlog — это формат логирования на базе JSON, созданный специально для QUIC и HTTP/3. Его поддерживает большинство реализаций QUIC. qlog не следит за тем, как пакеты проходят по сети, а записывает информацию сразу с клиента и сервера, в том числе дополнительные детали (например, о контроле перегрузок). Собрать данные qlog при запуске серверов и клиентов можно с помощью переменной среды QLOGDIR. (В Firefox нужно задать network.http.http3.enable_qlog. Устройства Apple и Safari используют QUIC_LOG_DIRECTORY. Chrome пока не поддерживает qlog.)
Файлы qlog можно отправить в набор инструментов qvis на странице qvis.quictools.info. Там можно создать несколько расширенных интерактивных графиков для анализа трафика QUIC и HTTP/3. В qvis можно загрузить записи пакетов Wireshark (файлы .pcap), а еще он предлагает экспериментальную поддержку для файлов Chrome netlog, чтобы можно было анализировать поведение Chrome. Полные инструкции по qlog и qvis мы здесь приводить не будем, но вы можете посмотреть видео, почитать документ или послушать обсуждение. Или задайте вопросы мне, потому что я главный разработчик qlog и qvis. ;)
Я реалист и понимаю, что мало кто из читателей станет использовать Wireshark или qvis, потому что они очень узкоспециализированные. Но пока у нас мало альтернатив, так что я не советую масштабно тестировать производительность HTTP/3 без таких инструментов, потому что нужно чётко понимать, что конкретно происходит и с чем это связано — с самим протоколом или другими факторами.
Что всё это значит?
Как мы видели, HTTP/3 over QUIC требует сложной настройки. Что угодно может пойти не так. К сожалению, пока нет инструмента, который предоставил бы нужные детали на нужном уровне абстракции. Это очень мешает большинству разработчиков оценить потенциальные преимущества HTTP/3 для веб-сайтов или хотя бы проверить, что у них всё работает правильно.
Полагаться только на метрики высокого уровня опасно, потому что на них влияет очень много факторов (вроде нереалистичной симуляции сети, отсутствия функций на клиентах и серверах, только частичное использование HTTP/3 и т. д.). Даже если бы всё работало хорошо, как мы видели во второй части, различия между HTTP/2 и HTTP/3 в большинстве случаев были бы незначительными. Тем сложнее добиться чего-то внятного от общих инструментов без специализированной поддержки HTTP/3.
Учитывая все эти замечания, я не советую сравнивать производительность HTTP/2 и HTTP/3 в ближайшие месяцы. Лучше займитесь тщательной настройкой на серверах. Для этого проще всего использовать WebPageTest в сочетании с параметрами командной строки Google Chrome, а также curl для решения возможных проблем — пока это самая надёжная комбинация.
Заключение и выводы
Если вы прочитали всю серию и добрались до этого места, мои поздравления! Даже если вы читали выборочно, благодарю за интерес к этим удивительным новым протоколам. Сейчас я подведу итоги по всей серии, дам рекомендации на ближайшие месяцы и на год и оставлю ссылки на дополнительные ресурсы.
Итоги
Сначала в первой части мы узнали, что HTTP/3 мы затеяли ради базового транспортного протокола — QUIC. QUIC — преемник TCP, который перенял от него всё лучшее, включая TLS 1.3. Проблема в том, что TCP так распространён, в том числе установлен на всех промежуточных устройствах, что совершенно потерял гибкость и не развивается. QUIC использует UDP и почти полностью зашифрован, а значит — будем надеяться! — нам придется обновлять только конечные точки для добавления новых функций, а это проще. QUIC, к тому же, дает интересные новые возможности.
- Транспортное и криптографическое рукопожатие объединены, в отличие от TCP + TLS, и можно использовать преимущества 0-RTT.
- QUIC знает, что передает несколько независимых потоков байтов, и может по-умному обрабатывать потери и задержки, частично решая проблему блокировок HoL.
- QUIC-соединения можно переносить между сетями (т. н. миграция соединения), если пометить каждый пакет ID соединения.
- Гибкая структура пакетов QUIC (с фреймами) повышает эффективность, гибкость и расширяемость протокола.
Очевидно, что QUIC — это транспортный протокол нового поколения, который будет использоваться ещё очень много лет.
Во второй части мы критически оценивали новые функции, особенно с точки зрения производительности.
- QUIC нельзя волшебным образом ускорить (или замедлить) благодаря UDP, потому что QUIC использует почти такие же механизмы контроля перегрузок, как TCP.
- Быстрые рукопожатия и 0-RTT ненамного повышают производительность, потому что позволяют сэкономить всего один круг по сравнению с оптимизированным стеком TCP + TLS, а настоящий 0-RTT ограничен соображениями безопасности.
- Миграция соединения полезна только в редких сценариях, и скорость всё равно придется сбрасывать из-за контроля перегрузок, потому что неизвестно, какая полоса пропускания у новой сети.
- Эффективность отсутствия блокировки HoL в QUIC во многом зависит от мультиплексирования и приоритизации потоков. Оптимальные подходы к восстановлению в случае потери пакетов мешают другим полезным механизмам и наоборот, хотя тут нужно больше исследований.
- QUIC может отправлять пакеты медленнее, чем TCP + TLS, потому что UDP API пока не так развиты, а QUIC шифрует каждый пакет по отдельности, хотя со временем ситуация может улучшиться.
- HTTP/3 сам по себе не содержит заметных новых функций, только переработанные и упрощённые варианты известных функций HTTP/2.
- Некоторые самые интересные функции QUIC, связанные с производительностью (multipath, ненадёжные данные, WebTransport, forward error correction и т. д.) не входят в стандарт QUIC и HTTP/3, а предлагаются как расширения и пока не доступны.
Это значит, что QUIC, скорее всего, особо не улучшит производительность для пользователей в быстрых сетях, но может принести пользу для медленных и нестабильных соединений.
Наконец, в третьей части мы узнали, как на практике использовать и развёртывать QUIC и HTTP/3.
- Мы увидели, что лучшие методы и уроки, извлечённые из использования HTTP/2, можно просто перенести на HTTP/3. Не нужно менять стратегию объединения в пакеты или встраивания, консолидировать или разделять серверную ферму. Server push пока лучше не использовать, а preload — прекрасный способ выстрелить себе в ногу.
- Придётся подождать, пока готовые пакеты веб-серверов начнут полностью поддерживать HTTP/3 (отчасти из-за проблем с поддержкой библиотеки TLS), хотя уже сейчас доступны опенсорс-версии, и у нескольких крупных CDN есть вполне зрелые предложения.
- Почти все основные браузеры предлагают базовую поддержку HTTP/3, причём даже по умолчанию. Они очень по-разному используют HTTP/3 и его новые функции и разобраться в этом сложно.
- Популярные инструменты, вроде Lighthouse и WebPageTest, толком не поддерживают HTTP/3, поэтому почти невозможно адекватно сравнить производительность HTTP/3 и HTTP/2 или HTTP/1.1.
В заключение: HTTP/3 и QUIC пока не вполне готовы для полноценного использования, но вскоре ситуация исправится.
Рекомендации
Если почитать итоги, может показаться, что я всех отговариваю от QUIC и HTTP/3. А я, наоборот, всеми руками за.
В конце второй части я уже говорил, что хотя для среднего пользователя чуда не случится (всё зависит от вашего целевого рынка), для многих улучшения производительности будут очень заметны. 0-RTT позволяет сэкономить всего один круг, но для некоторых пользователей это сотни миллисекунд. Миграция соединения не поддержит быструю загрузку, но придётся очень кстати, если вы пытаетесь скачать PDF в скоростном поезде. В проводных сетях пакеты могут теряться пачками, а беспроводные смогут использовать преимущества удаление блокировки HoL в QUIC. Более того, у этих пользователей самая низкая производительность при использовании вашего продукта, и как раз для них ситуация станет намного лучше. Если не знаете, почему это так важно, прочтите знаменитую историю Криса Закариаса (Chris Zacharias).
Во-вторых, QUIC и HTTP/3 со временем будут становиться только лучше. В первой версии реализованы основы протокола, всё самое интересное нас ждёт впереди. Поэтому советую уже сейчас заняться эти вопросом, и когда новые функции появятся, вы уже сможете эффективно использовать их. Это сложный протокол со сложным развёртыванием, так что на его изучение уйдёт время. Если сейчас вы пока не хотите с этим разбираться, некоторые крупные провайдеры CDN уже предлагают готовую поддержку HTTP/3 (особенно Cloudflare и Fastly). Не вижу никаких препятствий попробовать новый протокол, если вы уже используете CDN (а если вас волнует производительность, вы его, конечно, используете).
Не могу сказать, что нужно как можно скорее переходить на QUIC и HTTP/3, но они уже дают много преимуществ, и дальше их будет только больше.
Дополнительные ресурсы
Знаю, вам и так пришлось много прочитать, и это только верхушка айсберга.
Ниже вы найдете дополнительные ресурсы, от более простых к более техническим:
-
HTTP/3 Explained, Daniel Stenberg
Электронная книга от создателя cURL с общим описанием протокола.
-
HTTP/2 in Action, Barry Pollard
Потрясающая книга с полным описанием HTTP/2, из которой можно почерпнуть полезные советы и для HTTP/3. Плюс глава о новом протоколе.
-
@programmingart, Twitter
Я пишу твиты о QUIC, HTTP/3 и веб-производительности, в том числе делюсь новостями на эту тему. Вот, например, твит о последних трендах для функций QUIC.
-
YouTube, Robin Marx
10 подробных выступлений о разных аспектах протокола.
- The Cloudflare Blog
Это главный продукт компании, которая делает ещё и CDN.
-
The Fastly Blog
В этом блоге обсуждаются технические аспекты, вписанные в широкий контекст.
-
QUIC, RFC
Ссылки на документы по IETF QUIC и HTTP/3 RFC и другие официальные расширения.
-
IIJ Engineers Blog
Подробные технические разъяснения функций QUIC.
-
HTTP/3 и QUIC исследования, Robin Marx
В своих исследованиях я рассматриваю приоритизацию и мультиплексирование потоков, инструменты и различия в реализациях.
-
QUIPS, EPIQ 2018 и EPIQ 2020
Подробные исследования на тему безопасности, производительности и расширений новых протоколов.
Надеемся, эта серия помогла вам гораздо лучше понять новые протоколы. Автор всегда открыт для обратной связи и ждёт ваших мнений о серии статей!
Комментарии (10)
happy-cat
10.11.2021 14:14Очень похоже на IPV6 - так же круто, так же гиморойно настраивать, в итоге провайдеры (в Москве, МГТС) его массово не поддерживают, браузеры с http v3 в своей массе работают через пень колоду... имхо лет через несколько, maybe, может взлететь, пока даже не буду терять времени на их настройку (хотя краем глаза посматриваю на новости с полей)
amarao
10.11.2021 16:46+1Ой, не кладите вместе ipv6 и quic. IPv6 вобрал в себя столько улучшений по сравнению с ipv4, что после какого-никакого опыта работы с ipv6, возврат в волшебный мир бушующих бродкастных arp'ов звучит как кошмар. Причём, если пытаться описать ipv4 с позиции ipv6, то там дичь на дичи. Например, как узнать IP-адрес маршрутизатора в сети? Отправить бродкаст (!) на всю сеть, в ответ на которую придёт NACK, после чего опять нужно отправить запрос, и может быть, в финале придёт ACK и мы узнаем... Свой ip адрес. А шлюз - это позднее расширение, вовсе не обязательное.
Как общаться, если нет DHCP? ЛИбо никак, либо ждать чёрти сколько и пытаться прихватизировать адрес из малюсенькой сетки с огромными шансами на коллизию и нулевой discoverability (предсказать link-local узла в ipv4 невозможно). Как узнать, какие узлы есть в сети? Бродкаст! Как напомнить о своём существовании коммутатору? Бродкаст! Да ещё и не на IP уровне, а чёрти на каком протоколе. 100.500 - валидный ip адрес!
Это мы ещё не тронули нежный вопрос NAT'а и совершенно не покрытого стандартами multihoming'а.
Вы привыкли к ipv4, и вам не хочется переучиваться. А пользы от ipv6 очень много на всех слоях, буквально, куда не ткни, улучшение.
happy-cat
10.11.2021 17:53Я с вами полностью согласен, вы мне даже как то на QNA.habr помогали с IPV6, у меня даже все заработало (тогда я хостился на Хецнере) но, имхо домашние провайдеры пока почему то не разделяют ваши восторги, а уж у них я надеюсь сетевые инженеры не зря едят свой хлеб... \_(ツ)_/¯
korsetlr473
10.11.2021 15:40на cloudflare в 1 клик включается без каких либо настроек в твоем коде.
Я был невероятно удивлен скорости
SergeiMinaev
10.11.2021 19:02+1На практике было очень сложно перейти на одно соединение, потому что многие страницы были разделены между именами хостов и даже серверами (например,
img1.example.com
иimg2.example.com
).А нужно ли прям переходить на одно соединение? Иметь три-четыре соединения вместо одного - не такие уж большие накладные расходы, если у вас не десятки тысяч мелких запросов в секунду.
Так что всем советовали отменить шардинг между серверами и по максимуму собрать ресурсы на одном сервере. У HTTP/2 даже была функция объединения соединений
Ага, а потом окзалось, что на нестабильных соединениях HTTP/2 медленнее, чем HTTP/1 из-за того, что потери пакетов блочат всё соединение (с чем и призван бороться HTTP/3), но у HTTP/1 их как минимум шесть :)
файловые запросы до сих пор обходятся не так дёшево, как все изначально ждали от HTTP/2. Наконец, если не встраивать ресурсы, это увеличивает задержку, потому что файлы нужно запрашивать.
Вот да, мне кажется, не все это понимают. Как ни крути, а самый эффективный способ - загрузить всё, что нужно, за один раз.
Мы видели, что система была очень сложной, часто ее неправильно использовали и реализовывали на практике
Согласен, это - большой недостаток HTTP/2 :(
В целом, лучше не использовать server push для загрузки веб-страниц, разве что вы точно знаете, что делаете. Но и тогда большого преимущества вы не получите.
И тут согласен. И получается интересная ситуация - сначала о приоритезации и сервер-пушах HTTP/2 изо всех щелей вылезали крайне хвалебные статьи, а потом бац и оказалось, что от них проблем больше, чем пользы. Поэтому я сейчас уже скептически смотрю к нововведениям, преподносимым как преимущества в HTTP/3. Как минимум, 0-RTT выглядит сомнительно из-за проблем с безопасностью. И кажется немного неправильным, что ради небольшого преимущества в нестабильных сетях, HTTP/3 более ресурсоёмок в плане шифрования, и это работает впустую в стабильных сетях. Но, конечно, это не означает, что надо стоять на месте.
Интересная статья, спасибо.
LifeSweetener
11.11.2021 09:37Вау, спасибо Вам за такую полезную и о-очень полную статью, Полина!)
Всё очень подробно с мельчайшими деталями и пояснениями к ним. Теперь мы знаем, что появился HTTP/3!
achekalin
14.11.2021 22:11Очевидно, что QUIC — это транспортный протокол нового поколения, который будет использоваться ещё очень много лет.
Ну вот с "очевидно" я бы не торопился. Очевидно, что его пиарят (Гугл), очевидно, что юзабельных реализаций в веб-серверах - что-то кот наплакал. В браузерах, внезапно, тоже требуются порой танцы для включения.
Итого, "из коробки" в сервере не включить, у клиента будет ли востребовано - не понятно. По сетям зажатие UDP у иного транзитного оператора может подкинуть свинью совершенно легко.
В общем, если поиграться - то ок, а для работающих сайтов можно и не морочиться. Пока что не морочиться.
amarao
В целом, quic идёт в тренде браузеров - усложнять стандарты до тех пор, пока не останется один-единственный клиент, который это всё способен поддерживать; и стоимость его реализации будет так высока, что никто больше никогда не создаст ещё одну реализацию.
В стандартах www мы это уже видим - браузеры вымирают, не выдержав конкуренции. IE ушёл, опера ушла. FF ещё держится, но в целом, webkit сжирает всё. И это плохо, потому что тогда решения о том, каким будет интернет, начинают принадлежать банде с максимальной скоростью коммитов. Death by thousands MRs, так сказать.
Вот то же самое и с транспортом пытаются сделать. И это плохо, потому что чем шире и сложнее спецификация, тем хуже относительная компетенция у разработчиков.
shai_hulud
HTTP/1.0 можно реализовать на коленке, один запрос = одно подключение, пишешь заголовки и тело, читаешь ответ и тело. Код простой и однопоточный. Может написать даже джун.
HTTP/1.1 можно реализовать немного подумав, ведь теперь одно подключение = несколько запросов подряд, заголовков стало больше, правил и исключений больше. Реализация все еще может быть тупой и однопоточной. По причине сложности и нуансов появились атаки типа HTTP Request Smuggling и другие. По причине того что обычным разработчикам не интересно читать 100 страниц документации, у нас теперь нельзя послать GET запрос с телом в большинстве HTTP клиентов, хотя стандарт не запрещает.
HTTP/2.0 добавил мультиплексинг потоков, HD-сжатие заголовков и стейт машины на подключение и потоки каждого запроса. Теперь для реализации уже нужно писать асинхронный код, трекать стейт машины, реализовывать алгоритмы сжатия. Для реализации нужен человек с опытом, вариантов наделать ошибок много.
HTTP/3.0 читал бегло, думать о реализации страшно т.к. надо еще читать и понять DTLS.
shai_hulud
Причем HTTP/2.0 еще с натяжкой можно называть развитием технологии и решением общих проблем доставки контента на уровне приложений, то HTTP/3.0 это решение узкого круга проблеем одного игрока - Гугла. Как их протокол протолкнули как стандарт - хз. HTTP/2.0 еще не массово внедрен (46%) и не вышел на плато, что бы его заменять. Если кто-то знает обоснование для третьей версии, то пожалуйста скиньте ссылку или процитируйте.