предисловие
Обычно мы говорим о блокировке заголовка строки, которая может относиться к блокировке заголовка строки в протоколе TCP, но HTTP1.1 также имеет проблему, аналогичную блокировке заголовка строки TCP, которая будет представлена ниже.
Блокировка заголовка очереди TCP
Блокировка заголовка строки происходит, когда сегмент TCP потерян, что приводит к тому, что его последующие сегменты приходят к получателю не по порядку. Последующий сегмент будет удерживаться получателем до тех пор, пока потерянный первый сегмент не будет повторно передан отправителем и не достигнет получателя. Задержка доставки этого последующего сегмента гарантирует, что принимающий прикладной процесс сможет получить данные в том порядке, в котором они были отправлены отправителем. Этот механизм задержки, введенный для достижения полного упорядочения, очень полезен, но он также имеет недостатки.
Предполагая, что семантически независимые сообщения отправляются через одно TCP-соединение, скажем, сервер может отправить 3 разных изображения для отображения в веб-браузере. Чтобы создать эффект параллельного отображения этих изображений на экране пользователя, сервер сначала отправляет фрагмент первого изображения, затем фрагмент второго изображения, а затем фрагмент третьего изображения, сервер повторяет этот процесс. пока все 3 изображения не будут успешно отправлены в браузер.
Если TCP-сегмент содержимого фрагмента первого изображения утерян, клиент сохранит все данные, пришедшие не по порядку, до тех пор, пока потерянный сегмент не будет успешно повторно передан. Это не только задерживает доставку данных первого изображения, но также задерживает доставку данных второго и третьего изображения.
Блокировка заголовка очереди HTTP
В приведенном выше примере используется браузер для запроса ресурсов изображения в качестве примера, но на самом деле сам HTTP также имеет ситуацию, аналогичную ситуации с блокировкой заголовка очереди TCP. Чтобы ввести блокировку заголовка строки HTTP, нам нужно поговорить о конвейерной обработке HTTP.
Что такое конвейерная обработка HTTP
HTTP 1.1 позволяет дополнительно использовать конвейеры запросов через постоянные соединения. Это еще одна оптимизация производительности по сравнению с поддерживающими соединениями. До соответствующих поступлений несколько запросов могут быть поставлены в очередь.Когда первый запрос отправляется на сервер, второй и третий запросы также могут быть отправлены.В условиях сети с высокой задержкой это может уменьшить сетевой цикл.Время возврата и улучшить производительность.
Разница между беспроводным и трубным
Предыстория конвейерной обработки HTTP
В общем, HTTP следует модели «запрос-ответ», то есть каждый раз, когда клиент отправляет запрос на сервер, сервер возвращает ответ. Этот режим очень прост для понимания, но эффективность не так высока.Чтобы улучшить скорость и эффективность, люди предприняли много попыток:
- В простейшем случае, как только сервер возвращает ответ, он закрывает соответствующее соединение, и несколько запросов от клиента фактически отправляются последовательно.
- Кроме того, клиент может одновременно создавать несколько подключений и отправлять разные запросы параллельно по нескольким подключениям. Но создание большего количества подключений также увеличивает потребление, и большинство браузеров в настоящее время ограничивают количество подключений к одному и тому же доменному имени.
- Начиная с HTTP 1.0, была добавлена концепция постоянного соединения (Keep-Alive в HTTP 1.0 и постоянное в HTTP 1.1), которое позволяет HTTP повторно использовать уже созданные соединения. После получения ответа от сервера клиент может повторно использовать предыдущее соединение для отправки следующего запроса без повторного установления соединения.
- Большинство современных браузеров используют параллельные соединения и постоянные соединения для повышения скорости доступа и устанавливают небольшое количество постоянных соединений параллельно для каждого доменного имени.
- На основе постоянных соединений HTTP 1.1 дополнительно поддерживает использование функций конвейерной обработки для постоянных соединений. Конвейерная обработка позволяет клиенту отправить следующий запрос до того, как отправленный запрос получит ответ от сервера, тем самым сокращая время ожидания и улучшая пропускную способность; если несколько запросов могут быть отправлены в одном и том же разделе TCP, это также может улучшить использование сети. Но поскольку конвейерная обработка HTTP сама по себе может вызвать проблемы с блокировкой заголовка строки, современные браузеры по умолчанию отключили конвейерную обработку.
Ограничения конвейерной обработки HTTP
- Конвейерная обработка требует, чтобы сервер возвращал ответы (FIFO) в том порядке, в котором отправляются запросы. Причина очень проста: HTTP-запросы и ответы не имеют порядковых номеров, поэтому невозможно связать неупорядоченные ответы с запросами. .
- Клиенту необходимо сохранить неотвеченный запрос, а когда соединение неожиданно прервется, ему необходимо повторно отправить эту часть запроса.
- Только идемпотентные запросы могут быть конвейерными, то есть могут быть конвейерными только запросы GET и HEAD, в противном случае могут возникнуть неожиданные результаты.
Блокировка заголовка запроса, вызванная конвейерной обработкой HTTP
Как упоминалось ранее, конвейерная обработка HTTP требует, чтобы сервер возвращал ответы в том порядке, в котором отправляются запросы.Если ответ задерживается, последующие ответы будут откладываться до тех пор, пока не будет доставлен ответ из головы очереди.
Как решить первую блокировку
Как решить блокировку заголовка очереди HTTP
Для блокировки заголовка на уровне запроса/ответа, вызванной конвейерной обработкой в HTTP1.1, для ее решения можно использовать HTTP2. HTTP2 не использует конвейерный метод, но вводит такие понятия, как кадры, сообщения и потоки данных.Каждый запрос/ответ называется сообщением, и каждое сообщение разбивается на несколько кадров для передачи, и каждому кадру присваивается порядковый номер. Каждый кадр принадлежит потоку данных в процессе передачи, и в соединении может быть несколько потоков.Каждый кадр передается независимо от потока и соединения и собирается в сообщение после прибытия, что позволяет избежать блокировки запроса/ответа.
Конечно, даже если используется HTTP2, если базовым протоколом HTTP2 является TCP, все еще может иметь место блокировка заголовка TCP.
Как решить блокировку заголовка очереди TCP
Генерация блокировки заголовка строки в TCP определяется механизмом реализации самого TCP, и ее нельзя избежать. Если вы хотите избежать влияния блокировки заголовка строки TCP в своем приложении, вы можете только отказаться от протокола TCP.
такие как гуглquicМожно сказать, что протокол в определенной степени позволяет избежать блокировки заголовка строки в TCP, поскольку он вообще не использует протокол TCP, а реализует надежную передачу на основе протокола UDP. UDP — это протокол, ориентированный на дейтаграммы, и между дейтаграммами нет блокирующих ограничений.
Кроме того, существует SCTP (протокол передачи управления потоком), который является протоколом передачи того же уровня, что и TCP и UDP. Многопоточная функция SCTP также позволяет максимально избежать блокировки очереди.
Суммировать
Из причин блокировки заголовка строки TCP и блокировки заголовка строки HTTP мы видим, что существует две причины блокировки заголовка строки:
- Независимые данные сообщения передаются по ссылке, то есть существует «очередь». Например, TCP имеет только один поток, а несколько HTTP-запросов совместно используют TCP-соединение.
- Данные, передаваемые в очередь, имеют строгие ограничения по порядку. Например, TCP требует, чтобы данные были строго в порядковом номере, а конвейер HTTP требует, чтобы ответы возвращались строго в порядке запросов.
Поэтому, чтобы избежать блокировки заголовка строки, необходимо исходить из двух вышеуказанных аспектов, например, протокол quic использует не протокол TCP, а протокол UDP, а протокол SCTP поддерживает несколько потоков данных на одном соединении. .