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, чтобы получить это, и вместо этого выпустили то, что у них есть, как шаг впереди.