Что означает мультиплексирование в HTTP / 2


Ответы:


221

Проще говоря, мультиплексирование позволяет вашему браузеру запускать несколько запросов одновременно по одному и тому же соединению и получать запросы обратно в любом порядке.

А теперь гораздо более сложный ответ ...

Когда вы загружаете веб-страницу, она загружает HTML-страницу, видит, что ей нужен некоторый CSS, немного JavaScript, загрузка изображений ... и т. Д.

В HTTP / 1.1 вы можете загружать только один из них за раз по вашему HTTP / 1.1 соединению. Итак, ваш браузер загружает HTML-код, а затем запрашивает файл CSS. Когда он возвращается, он запрашивает файл JavaScript. Когда он возвращается, он запрашивает первый файл изображения ... и т. Д. HTTP / 1.1 в основном синхронный - как только вы отправляете запрос, вы зависаете, пока не получите ответ. Это означает, что большую часть времени браузер не делает очень много, так как он отправил запрос, ожидает ответа, затем запускает другой запрос, затем ждет ответа ... и т. Д. Конечно, сложные сайты с многие JavaScript действительно требуют, чтобы браузер выполнял большую обработку, но это зависит от загружаемого JavaScript, поэтому, по крайней мере, для начала, задержки, наследуемые HTTP / 1.1, действительно вызывают проблемы. Обычно сервер не работает.

Таким образом, одна из основных проблем в Интернете сегодня - это задержка в сети при отправке запросов между браузером и сервером. Это могут быть десятки или, возможно, сотни миллисекунд, что может показаться немного, но они складываются и часто являются самой медленной частью просмотра веб-страниц, особенно когда веб-сайты становятся более сложными и требуют дополнительных ресурсов (по мере их поступления) и доступа в Интернет. все чаще осуществляется через мобильные устройства (с меньшей задержкой, чем у широкополосного доступа).

В качестве примера предположим, что есть 10 ресурсов, которые ваша веб-страница должна загрузить после загрузки самого HTML (что является очень маленьким сайтом по сегодняшним стандартам, так как более 100 ресурсов является обычным явлением, но мы будем простыми и пойдем с этим пример). Допустим, каждый запрос проходит через Интернет на веб-сервер и обратно за 100 мс, а время обработки на обоих концах незначительно (для простоты скажем, 0 для этого примера). Поскольку вам нужно отправлять каждый ресурс и ждать ответа по одному, загрузка всего сайта займет 10 * 100 мс = 1000 мс или 1 секунду.

Чтобы обойти это, браузеры обычно открывают несколько подключений к веб-серверу (обычно 6). Это означает, что браузер может отправлять несколько запросов одновременно, что намного лучше, но за счет сложности настройки и управления несколькими подключениями (что влияет как на браузер, так и на сервер). Продолжим предыдущий пример и также предположим, что имеется 4 соединения и для простоты предположим, что все запросы равны. В этом случае вы можете разделить запросы по всем четырем соединениям, так что у двух будет 3 ресурса для получения, а у двух будет 2 ресурса для получения всех десяти ресурсов (3 + 3 + 2 + 2 = 10). В этом случае наихудший случай - 3 раунда или 300 мс = 0,3 секунды - хорошее улучшение, но этот простой пример не включает стоимость настройки этих нескольких соединений,

HTTP / 2 позволяет отправлять несколько запросов в один и тот жесоединение - поэтому вам не нужно открывать несколько соединений, как указано выше. Итак, ваш браузер может сказать: «Дайте мне этот файл CSS. Дайте мне этот файл JavaScript. Дайте мне image1.jpg. Дайте мне image2.jpg ... и т. Д.» чтобы полностью использовать одно-единственное соединение. Это дает очевидное преимущество в производительности, так как не задерживает отправку запросов, ожидающих свободного соединения. Все эти запросы проходят через Интернет на сервер (почти) параллельно. Сервер отвечает на каждый из них, а затем они начинают возвращаться. На самом деле он даже более мощный, чем это, поскольку веб-сервер может отвечать на них в любом порядке, который он чувствует, и отправлять файлы обратно в другом порядке или даже разбивать каждый запрошенный файл на части и смешивать файлы вместе.проблема блокировки головы линии ). Затем веб-браузеру предлагается собрать все части вместе. В лучшем случае (при условии отсутствия ограничений пропускной способности - см. Ниже), если все 10 запросов запускаются практически одновременно параллельно и на них сервер немедленно отвечает, это означает, что у вас в основном есть один круговой обход или 100 мс или 0,1 секунды, чтобы скачать все 10 ресурсов. И в этом нет недостатков, которые были у нескольких подключений для HTTP / 1.1! Это также становится намного более масштабируемым по мере роста ресурсов на каждом веб-сайте (в настоящее время браузеры открывают до 6 параллельных подключений по протоколу HTTP / 1.1, но должно ли это расти по мере того, как сайты становятся более сложными?).

На этой диаграмме показаны различия, а также есть анимированная версия .

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

В комментариях ниже подчеркивается, как на нас влияет пропускная способность. Конечно, ваше интернет-соединение ограничено тем, сколько вы можете загрузить, и HTTP / 2 не решает эту проблему. Так что, если все 10 ресурсов, описанных в примерах выше, представляют собой массивные изображения с качеством печати, их загрузка все равно будет медленной. Однако для большинства веб-браузеров пропускная способность представляет меньшую проблему, чем задержка. Поэтому, если эти десять ресурсов представляют собой небольшие элементы (в частности, текстовые ресурсы, такие как CSS и JavaScript, которые можно сжать до крошечного размера), как это часто бывает на веб-сайтах, то пропускная способность на самом деле не проблема - это просто объем ресурсов, который часто проблема, и HTTP / 2 пытается решить эту проблему. Вот почему конкатенация используется в HTTP / 1.1 в качестве другого обходного пути, поэтому, например, весь CSS часто объединяется в один файл:антипаттерн в HTTP / 2 - хотя есть аргументы против полного отказа от него).

Чтобы представить это как реальный пример: предположим, вам нужно заказать в магазине 10 товаров с доставкой на дом:

  • HTTP / 1.1 с одним подключением означает, что вы должны заказывать их по одному, и вы не можете заказать следующий элемент, пока не будет доставлен последний. Вы понимаете, что на то, чтобы все пережить, потребуются недели.

  • HTTP / 1.1 с несколькими подключениями означает, что вы можете иметь (ограниченное) количество независимых заказов на ходу одновременно.

  • HTTP / 1.1 с конвейерной обработкой означает, что вы можете запросить все 10 элементов один за другим, не дожидаясь ожидания, но затем все они будут доставлены в том порядке, в котором вы их просили. И если одного товара нет в наличии, вам придется подождать, прежде чем вы получите товары, которые вы заказали после этого - даже если эти более поздние товары действительно есть в наличии! Это немного лучше, но все же возможны задержки, и, допустим, большинство магазинов все равно не поддерживают этот способ заказа.

  • HTTP / 2 означает, что вы можете заказывать свои товары в любом порядке - без каких-либо задержек (как указано выше). Магазин отправит их по мере их готовности, поэтому они могут прибыть в другом порядке, чем вы просили, и они могут даже разделить товары, чтобы некоторые части этого заказа были доставлены первыми (так лучше, чем указано выше). В конечном итоге это должно означать, что вы 1) получаете все быстрее и 2) можете начинать работу над каждым элементом по мере его поступления («о, это не так хорошо, как я думал, поэтому я мог бы заказать что-то еще или вместо этого» ).

Конечно, вы все еще ограничены размером фургона вашего почтальона (пропускной способностью), поэтому им, возможно, придется оставить некоторые пакеты обратно в сортировочном офисе до следующего дня, если они будут заполнены на этот день, но это редко проблема по сравнению к задержке фактической отправки заказа туда и обратно. В большинстве случаев просмотр веб-страниц подразумевает отправку туда и обратно небольших писем, а не объемных пакетов.

Надеюсь, это поможет.


8
Замечательное объяснение. Пример - вот что мне нужно, чтобы получить это. Таким образом, в HTTP / 1.1 между ожиданием ответа и отправкой следующего запроса происходит пустая трата времени. HTTP / 2 исправляет это. Спасибо.
user3448600 09

1
Но сурово я считаю. Мог бы просто попросить меня добавить статью о пропускной способности - что я счастлив сделать и сделаю после того, как мы закончим это обсуждение. Однако IMHO Bandwidth не такая большая проблема для просмотра веб-страниц (по крайней мере, в западном мире) - задержка. А HTTP / 2 улучшает задержку. Большинство веб-сайтов состоят из множества небольших ресурсов, и даже если у вас есть пропускная способность для их загрузки (как это часто делают люди), загрузка будет медленной из-за задержки в сети. Пропускная способность становится все более серьезной проблемой для больших ресурсов. Я согласен с тем, что эти веб-сайты с большими изображениями и другими ресурсами могут по-прежнему достигать предела пропускной способности.
Барри Поллард

1
HTTP не следует использовать для принудительного упорядочивания, потому что он не дает таких гарантий. С HTTP / 2 вы можете предлагать приоритет доставки, но не заказ. Также, если один из ваших ресурсов JavaScript кэширован, а другой нет, тогда HTTP не может повлиять даже на приоритет. Вместо этого вам следует использовать упорядочивание в HTML вместе с соответствующим использованием async или defer ( growwiththeweb.com/2014/02/async-vs-defer-attributes.html ) или библиотеки, такой как require.js.
Барри Поллард

1
Отличное объяснение. Спасибо!
hmacias

2
Это потому, что HTTP / 1.1 - это поток текста, а HTTP / 2 основан на пакетах - в HTTP / 2 они называются фреймами, а не пакетами. Таким образом, в HTTP / 2 каждый кадр может быть помечен как поток, что позволяет чередовать кадры. В HTTP / 1.1 такой концепции нет, поскольку это просто набор текстовых строк для заголовка, а затем тела. Подробнее здесь: stackoverflow.com/questions/58498116/…
Барри Поллард

4

Простой ответ ( источник ):

Мультиплексирование означает, что ваш браузер может отправлять несколько запросов и получать несколько ответов, «объединенных» в одно TCP-соединение. Таким образом, рабочая нагрузка, связанная с поиском в DNS и подтверждением связи, сохраняется для файлов, поступающих с одного и того же сервера.

Сложный / подробный ответ:

Обратите внимание на ответ @BazzaDP.


1
это может быть достигнуто с помощью конвейерной обработки также в http 1.1. Основная цель мультиплексирования в HTTP2 - не ждать ответов в упорядоченном порядке,
Дхайрья Лакхера

4

Мультиплексирование в HTTP 2.0 - это тип отношений между браузером и сервером, которые используют одно соединение для параллельной доставки нескольких запросов и ответов, создавая в этом процессе множество отдельных кадров.

Мультиплексирование выходит за рамки строгой семантики запроса-ответа и позволяет устанавливать отношения «один ко многим» или «многие ко многим».

HTTP1 VS HTTP2 процесс обмена


Ваш пример мультиплексирования HTTP / 2 на самом деле не показывает мультиплексирование. Сценарий на вашей диаграмме показывает конвейерную обработку HTTP, которая была введена в HTTP / 1.1.
ich5003

@ ich5003 Это мультиплексирование, потому что используется одно соединение. Но верно и то, что здесь не представлены случаи отправки нескольких ответов на один запрос.
Juanma Menendez

1
Я пытаюсь сказать, что показанный выше сценарий также возможен только с использованием конвейерной обработки HTTP.
ich5003

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

4

Запросить мультиплексирование

HTTP / 2 может отправлять несколько запросов данных параллельно через одно TCP-соединение. Это наиболее продвинутая функция протокола HTTP / 2, поскольку она позволяет загружать веб-файлы асинхронно с одного сервера. Большинство современных браузеров ограничивают TCP-соединения одним сервером. Это сокращает дополнительное время приема-передачи (RTT), ускоряет загрузку вашего веб-сайта без какой-либо оптимизации и делает ненужным сегментирование домена.

введите описание изображения здесь


1

Поскольку ответ @Juanma Menendez правильный, а его диаграмма сбивает с толку, я решил улучшить ее, прояснив разницу между мультиплексированием и конвейерной обработкой, понятиями, которые часто смешивают.

Конвейерная обработка (HTTP / 1.1)

Несколько запросов отправляются через одно и то же HTTP-соединение. Ответы приходят в том же порядке. Если первый ответ занимает много времени, другие ответы должны ждать в очереди. Подобно конвейерной передаче ЦП, когда одна инструкция выбирается, пока другая декодируется. Одновременно выполняется несколько инструкций, но их порядок сохраняется.

Мультиплексирование (HTTP / 2)

Несколько запросов отправляются через одно и то же HTTP-соединение. Ответы принимаются в произвольном порядке. Не нужно ждать медленного ответа, который блокирует других. Подобно выполнению инструкций вне очереди в современных процессорах.

Надеюсь, улучшенное изображение проясняет разницу:

Стандартный поток HTTP / 1.1 / конвейерная обработка / мультиплексирование

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.