Пора в очередной раз проанализировать, в каком состоянии сейчас находится поддержка HTTP/3 в curl.
Думаю, ситуация с curl отражает положение дел во многих других HTTP-инструментах и библиотеках. HTTP/3 был и продолжает быть более сложным в плане развёртывания по сравнению с HTTP/2.
▍ cURL поддерживает четыре решения HTTP/3 на выбор
Поддержку HTTP/3 в curl можно реализовать с помощью четырёх разных подходов. Мы предоставляем несколько решений, чтобы на «рынке» был выбор, и чтобы они могли «конкурировать» друг с другом, давая пользователям возможность подобрать лучшее. Это избавляет нас от сложной задачи выбирать победителя изначально.
Подробнее обо всех этих четырёх подходах будет сказано ниже.
▍ Почему cURL ещё не использует HTTP/3?
Уже использует, если при сборке этого инструмента включить правильный набор сторонних библиотек. Кроме того, исполняемые файлы curl для Windows, предоставляемые проектом curl, поддерживают HTTP/3.
Для Linux, а также других дистрибутивов и упаковщиков операционных систем серьёзной проблемой остаётся то, что самая популярная библиотека TLS (OpenSSL) не предлагает широко поддерживаемый QUIC API, который предоставляют большинство других библиотек TLS. Напомню, что HTTP/3 задействует протокол QUIC (Quick UDP Internet Connections), внутренне использующий TLS 1.3. Это отсутствие API в OpenSSL вынуждает всех, кто хочет использовать библиотеку QUIC, использовать другую библиотеку TLS. Дело в том, что curl не предусматривает сборки с использованием нескольких библиотек TLS. Включение отдельной библиотеки TLS для QUIC наряду с другими протоколами на основе TLS не поддерживается.
Debian проводит эксперимент по внедрению HTTP/3 в поставляемую ими версию curl путём перехода на GnuTLS (и сборки с использованием ngtcp2 + nghttp3).
▍ Бэкенд HTTP/3
Чтобы curl заговорила на HTTP/3, потребуется три составляющих, а также корректировка кода самой программы:
- поддержка TLS 1.3 для QUIC;
- библиотека протокола QUIC;
- библиотека протокола HTTP/3.
▍ Наглядное представление
Ниже в разных столбцах условной схемы представлены четыре решения HTTP/3, поддерживаемые curl. Все, кроме крайнего правого, считаются экспериментальными.
Поддержка бэкенда HTTP/3 в curl на июнь 2024
Слева направо:
- Библиотека quiche поддерживает QUIC и HTTP/3, а также обеспечивает TLS с помощью BoringSSL.
- msh3 — это ещё одна библиотека HTTP/3, использующая mquic для QUIC и либо семейство форков, либо Schannel для TLS.
- nghttp3 — это библиотека HTTP/3, которая в этой конфигурации использует стек QUIC из OpenSSL, который реализует QUIC и TLS.
- nghttp3 для HTTP/3 с использованием ngtcp2 для QUIC позволяет задействовать различные библиотеки TLS: семейство форков, GnuTLS и wolfSSL. (picotls тоже поддерживается, но сама curl не поддерживает её в качестве дополнительного решения TLS).
▍ ngtcp2 лидирует
Тандем библиотек ngtcp2 и nghttp3 стал первой комбинацией QUIC и HTTP/3, предоставившей уже не бета, а полноценные версии, уверенно работающие с curl. И это основная причина, по которой мы рекомендуем предпочесть именно этот подход.
Также привлекает гибкость представленных этой вертикалью решений TLS, поскольку даёт возможность использовать множество разных библиотек. К сожалению, разработчики OpenSSL решили не участвовать в этой игре, так что в приведённой конфигурации потребуется другая библиотека TLS.
▍ OpenSSL QUIC
В OpenSSL 3.2 была добавлена реализация стека QUIC, миновавшая статус «беты», которую curl может использовать в качестве альтернативного решения. Впоследствии в OpenSSL 3.3 были внесены дополнительные доработки. С начала 2024 года curl можно собирать и использовать для HTTP/3, о чём говорилось выше.
Тем не менее API, предоставляемый OpenSSL для выполнения передачи, неполноценен. В нём не хватает важной функциональности, что делает его неэффективным и иногда вынуждает curl входить в холостые циклы, чтобы определить дальнейшие действия. Этот факт и, возможно, некоторые дополнительные проблемы делают реализацию OpenSSL QUIC значительно медленнее конкурентов. Ещё одна причина рассмотреть использование других решений.
Мы продолжаем общаться с командой OpenSSL о том, что ещё они могут добавить в свой API, чтобы мы могли использовать QUIC эффективно. Надеемся, они всё же внесут необходимые доработки.
Штефан Эйссинг построил хороший сравнительный график, который я взял из его презентации «Performance» (Штефан также писал о производительности h3 ранее). В графике сравнивается три бэкенда curl с поддержкой HTTP/3. (В него не включена msh3, поскольку в curl эта библиотека работает недостаточно хорошо).
Как видно ниже, в нескольких тестовых конфигурациях OpenSSL достигает примерно лишь половины уровня быстродействия в сравнении с другими бэкенд-решениями как в количестве запросов в секунду, так и в скорости передачи. Проверка проводилась на localhost, так что операции передачи, по сути, были привязаны к скорости процессора (cpu-bound).
Производительность бэкенда HTTP/3 в curl, запросов в секунду
Производительность бэкенда HTTP/3 в curl, мегабайтов в секунду
Я считаю, что команде OpenSSL, помимо улучшения API, также нужно поработать над быстродействием QUIC.
▍ quiche и msh3
- quiche по-прежнему отмечена как бета и использует только BoringSSL, что усложняет её применение во многих ситуациях.
- msh3 после недавнего рефакторинга вообще перестала работать в curl.
▍ HTTP/3 нагружает процессор
Это знает любой, кто следит за разработкой протокола. Я из раза в раз говорю об этом в каждой своей презентации, посвящённой HTTP/3. И хотя таких презентаций я провёл уже несколько, мне кажется, что повторять это стоит, и что составленные Штефаном графики отчётливо проясняют ситуацию.
HTTP/3 отличается медленной скоростью передачи, когда выполнение привязано к скорости работы процессора. Естественно, в большинстве ситуаций пользователи к ней не привязаны, поскольку обычно узким местом при передаче выступает ограниченная пропускная способность сети. HTTP/3, как правило, быстрее выполняет рукопожатие — благодаря QUIC — поэтому при передаче через него первый байт зачастую доставляется быстрее, чем через любую другую версию HTTP (по TLS).
Далее мы продемонстрируем всё это наглядно на примере других предоставленных Штефаном графиков, начав с рукопожатий, которые он осуществил со своей машины в Германии. В этих тестах использовалась сборка curl 8.8.0-DEV, предшествовавшая выходу curl 8.8.0.
Скорость выполнения рукопожатия в curl через HTTP/3 и HTTP/1.1
Нет, мы не можем объяснить, почему google.com обрабатывает рукопожатия по HTTP/3 медленнее. Можно добавить, что curl.se обслуживается Fastly CDN, поэтому фактически curl сравнивается в отношении реализаций CDN трёх разных поставщиков.
Скорость передачи по HTTP/3, HTTP/2 и HTTP/1.1 в curl
Опять же, эти передачи привязаны к быстродействию процессора, поэтому реально мы наблюдаем здесь огромный объём лишней работы ЦПУ, необходимой для их осуществления. Если же вы производительностью процессора не ограничены, то передачи, естественно, будут выполняться с одной скоростью, как и в старых версиях HTTP.
Все эти сравнения не являются обобщённой оценкой протокола (если такая вообще возможна) и показывают работу curl в отношении его конкретных версий. Мы не можем сделать вывод, что в коде curl есть проблемы или непродуманные решения, которые бы частично это объяснили. Лично я подозреваю, что хоть нам и есть всегда что доработать, вряд ли здесь скрываются какие-то ощутимые преграды для производительности. Но уверенными в этом быть тоже нельзя.
QUIC в OpenSSL здесь тоже выделяется, причём не самым привлекательным образом.
▍ Распространённость HTTP/3
Данные w3techs, Mozilla и Cloudflare сходятся в том, что около 28-30% веб-трафика на данный момент относится к HTTP/3, что превосходит охват HTTP/1.1.
Интересно в этих 30% то, что все крупные игроки и CDN (Google, Facebook, Cloudflare, Akamai, Fastly, Amazon и так далее) работают по HTTP/3, и я думаю, что все вместе они занимают гораздо больше 30%. Это говорит о том, что есть значительная доля браузерного трафика, который может задействовать HTTP/3, но пока этого не делает. К сожалению, найти этому объяснение возможности у меня нет.
▍ Обзор стека HTTPS
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (25)
vikarti
16.06.2024 15:50+1Это говорит о том, что есть значительная доля браузерного трафика, который может задействовать HTTP/3, но пока этого не делает. К сожалению, найти этому объяснение возможности у меня нет.
А разве из России на не-российские сайты QUIC в принципе работает?(спасибо в частности РКН)
А допустим из Китая и прочих Таджикистанов?
А во всяких Европах на мобильных сетях где DPI?
blind_oracle
16.06.2024 15:50Это же перевод, какое им дело до РФ и прочих Таджикистанов? :)
А Китай просто свой GFW скорее всего обновит новые паттерны искать и всё.
vikarti
16.06.2024 15:50Это я к тому что многим странам проще рубить QUIC нафиг благо все равно fallback'и есть и просто немного упадет скорость чем пробовать (что еще совсем не факт что получится) понять где там хотя бы адрес хоста.
blind_oracle
16.06.2024 15:50Ну всякие авторитарные режимы зарубят, а остальные будут пользоваться. Ну и там в QUIC более-менее обычный TLS1.3 в потрохах, написать дисскетор его для DPI не думаю что проблема.
TerekhinSergey
Во кто-нибудь может объяснить, почему все так в линуксе? Ну не хватает программе возможностей системной библиотеки - положи Альтернативу рядом с ней и используй. Или только хард код-путь? Только из системой папки... Снап вроде бы попытался, но не смог. В Windows проблема более-менее решена, а тут прям 90-е полным ходом
knstqq
снап - самая отвратительная штука что есть в убунте. Кладут каждую программу в образ по 300-500мб, всё тормозит, работает отвратительно.
+снап никто кроме canonnical не продвигает.
Если уж хочется запакетитироваться - Flatpack тогда.
p.s. про windows в 2024ом году сказать не могу, но в 2010ом году в windows решение было так себе. Постоянно приходится ставить "Visual C++ Redistributable for Visual Studio" или netframework, да ещё по 3-5 версий сразу. Исправили сейчас или всё ещё также ставятся?
opusmode
Да в общем-то уже лет 10 как поправили.
Точнее так - в 2015 в десятке уже точно всё было круто, а вот в 8.1 вроде бы таких проблем небыло и оно всё само, но память может подводить.
Но в целом я понимаю о чём вы. Семёрка была ужасна и восьмёрка сделала по ряду фронтов скачок вперёд, а уж десятка вообще сделала винду конфеткой. Хотя тоже не везде - powershell, относительно линуксов, всё ещё ужасен.
alan008
Всё так же, только версий .Net и С++ Redistributable стало гораздо больше :)
TerekhinSergey
Но при всём при том никто не говорит "ой, тут в системной библиотеке нет нужной нам функции, поэтому у нас лапки"
Starl1ght
Версия VCredist с 2015 года одна - последняя.
Неткоры - да, каждый отдельн
alan008
У меня другая информация насчет VC++:
Starl1ght
Если бы вы кликнули по ссылке download и запустили скачанное, то увидели бы именно то, что я и написал. Но вы этого не сделали.
И даже не погуглили, т.к. первая ссылка это
alan008
Не вижу смысла спорить, но точно существует несколько версий файла (возможно с одинаковой начинкой - это не проверял):
Мicrosoft Visual C++ 2015 Redistributable (x64) - 14.0.23026
Microsoft Visual C++ 2017 Redistributable (x64) - 14.16.27033
Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810
Starl1ght
Начиная с VC++ 2015 - ABI не менялся, и одного последнего редиста достаточно, чтобы работало всё. Я это и написал - в 2015+ - нужна одна последняя версия.
khajiit
А толку, если весь этот балаган тащат и устанавливают приложения, и плевать им на результаты гугла и написанное на сайте M$?
TerekhinSergey
Соглашусь про снап - но это была попытка, хотя и не очень удачная, решить эту и другие проблемы
domix32
у flatpak иногда схожие проблемы из-за "изоляции".
khajiit
Но он научился в зависимости
domix32
Насколько мне известно он дублирует по крайней мере часть из имеющихся зависимостей рядом.
khajiit
Ну, с контейнерным подходом дублирования никогда не избежать полностью, как это возможно с использованием только хоста — там уже пирог рискует получиться настолько сложным, что количество слоев начнет сказываться на быстродействии и надежности.
LF69ssop
Как раз в линуксе существует LD_PRELOAD. Ну или я не понял о чем вы.
winorun
Так ни кто так делать и не мешает. У меня три программы в /opt стоит. С полным набором библиотек. И это не считая игр в ~/Games, в которой некоторые библиотеки еще со времен Lenny.
Arenoros
тут речь не про рядовые зависимости типа boost, а что то в духе libatomic, pthread и с ними ещё можно относительно просто разобраться, а вот чтоб изолироваться от glibc это нужно столько приседаний сделать что одуреть можно, а в большинстве кодовых баз эти приседания в принципе не возможны (если интересны детали есть отличный доклад про это https://youtu.be/Z7WuUhPJ-cU)
В win чтоб запускать прогу собраную самым последним тулчейном vc на win7 достаточно просто поставить последний пакет Redistributable C++, а под linux чтоб мне запустить хоть что то собранное последним gcc на условной ubuntu 12.04 в общем случае вообще ни чего не сделать это практически нереально без полного обновления ОС включая ядро. найс портируемость linux.
vikarti
Технически - можно и способов существует много (можно вообще хоть все кроме glibc статически линковать). Просто принято использовать системное а не разводить свалку.
iamkisly
Либо я не понял сути проблемы, либо тут незнание матчасти. Поэтому я тут набросал пример, и зову
к коллайдеру !
Пример до убогости прост. Не по стандарту, gcc хавает.. но не суть
внимание на libhelloworld.so => not found
libhelloworld.so => /lib/x86_64-linux-gnu/libhelloworld.so
Тада!!
libhelloworld.so => helloworld/bin/libhelloworld.so
Пересобираем динамическую библиотеку
Не знаю зачем мне это понадобилось.. во имя LD_LIBRARY_PATH конечно