Как мультиплексирование HTTP / 2.0 работает с TCP? - PullRequest
0 голосов
/ 29 марта 2020

Я не являюсь опытным сетевым инженером, поэтому я надеюсь, что мой вопрос не выглядит расплывчатым или наивным.

В мультиплексировании в HTTP / 2.0, по-видимому, используется одно TCP-соединение для нескольких / разных запросов одновременно, так что мы Избегайте проблемы блокировки заголовка линии. Мне было интересно, как это работает / перекрывается с базовым TCP-соединением в смысле данных повторной сборки .

TCP также гарантирует, что данные (D), полученные на стороне получателя, восстанавливаются, даже если пакеты, составляющие D, получены не по порядку (или потеряны), чтобы собрать D обратно на принимающей стороне, а затем передать их приложение.

Мой вопрос таков: как понятие кадров в HTTP / 2.0 может сочетаться с / с повторной сборкой TCP-пакетов, чтобы составить целое сообщение на принимающей стороне? Какой из них происходит первым? Или какое отображение существует между кадрами и пакетами (один-к-одному, один-ко-многим и т. Д. c.)? В двух словах, как они работают вместе?

Ответы [ 2 ]

2 голосов
/ 29 марта 2020

HTTP / 2 пакеты отправляются как один или несколько пакетов TCP. Точно так же, как TCP-пакеты в конечном итоге отправляются в виде IP-пакетов (или дейтаграмм).

Это означает, что, хотя HTTP / 2 имеет мультиплексирование на прикладном уровне (HTTP), он не имеет действительно независимых потоков в транспортный уровень (TCP), и одной из проблем HTTP / 2 является то, что мы только что переместили проблему блокировки заголовка (HOL) с уровня HTTP на уровень TCP.

Давайте рассмотрим пример: Пример веб-страницы должен загрузить 10 изображений для отображения.

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

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

Однако, поскольку TCP является гарантированным по порядку протоколом, который не знает, для чего его использует приложение более высокого уровня (HTTP), это создает некоторые проблемы для HTTP / 2 в случае потери TCP-пакета.

Скажем, все эти 10 изображений возвращаются по порядку. Но пакет из первого изображения потерян. Теоретически, если HTTP / 2 действительно состоит из независимых потоков, браузер может отобразить последние 9 изображений, а затем повторно запросить отсутствующий пакет TCP и затем отобразить первое изображение. Вместо этого происходит то, что все 10 изображений задерживаются в ожидании повторного отправки пропущенного пакета TCP, прежде чем TCP даст знать верхнему уровню HTTP, какие сообщения были получены.

Таким образом, в среде с потерями HTTP / 2 работает значительно хуже, чем HTTP / 1.1 с 6-ю подключениями.

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

HTTP / 3 пытается решить оставшийся случай. Это достигается путем перехода от TCP к новому протоколу под названием QUI C, который сделан с идеей мультиплексирования, встроенного в него, в отличие от TCP. QUI C построен на UDP, а не на попытке создать совершенно новый протокол низкого уровня, поскольку он хорошо поддерживается. Но QUI C очень сложен и займет здесь некоторое время, поэтому они не задержали HTTP / 2, чтобы получить это, и вместо этого выпустили то, что у них есть, как шаг впереди.

2 голосов
/ 29 марта 2020

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

TCP не интерпретирует эти байты. Отправитель TCP просто упаковывает байты в кадры TCP и отправляет их вместе. Получатель TCP получает кадры TCP и повторно собирает байты, которые образуют последовательность кадров HTTP / 2.

TCP и HTTP / 2 на самом деле не работают вместе в том смысле, что TCP не знает, что это транспортировка - это просто серия непрозрачных байтов.

Таким образом, нет соответствия между кадрами TCP и кадрами HTTP / 2.

Учтите, что в большинстве случаев HTTP / 2 шифруется, поэтому у вас есть TCP, транспортирующий непрозрачные байты, которые оказываются байтами кадров TLS (возможно, фрагментированными - т. е. кадр TCP может содержать 1,5 кадра TLS, а оставшиеся байты кадра TLS находятся в последующем кадре TCP); каждый кадр TLS содержит непрозрачные байты, которые оказываются байтами HTTP / 2 (возможно также фрагментированными).

...