предисловие
Как фронтенд-разработчик🐶, HTTP является неотъемлемой частью нашей карты знаний, а также обязательным пунктом знаний для собеседований. HTTP2 претендует на то, чтобы сделать наши приложения быстрее, проще и стабильнее.Он отлично решает многие проблемы в версии 1.1.В этой статье мы с вами поговорим об улучшениях HTTP2.
История HTTP
Прежде чем мы официально поговорим о HTTP2, давайте поговорим об истории развития HTTP.
- HTTP/0.9 — однострочный протокол
HTTP был опубликован в 1990 г. В то время HTTP был очень простым: поддерживал только метод GET, заголовка не было, можно было получить только обычный текст. - HTTP/1.0 — платформа для построения протоколов
В 1996 году HTTP был официально выпущен в качестве стандарта, и версия была HTTP/1.0.В версии 1.0 были добавлены такие спецификации, как заголовки, коды состояния, разрешения, кэширование и длинные соединения (по умолчанию короткие соединения), которые, можно сказать, создают основная структура протокола. - HTTP/1.1 — дальнейшие улучшения
В 1997 году последовала версия 1.1. Основным улучшением версии 1.1 является длинное соединение по умолчанию, заставляющее клиента предоставлять заголовок Host, конвейер, Cache-Control, ETag и другие связанные расширения кэша.
существующие на данный момент проблемы
Сейчас не будем говорить о HTTP2, а посмотрим, какие проблемы существуют при разработке HTTP до 1.1:
- Блокировка начала строки: по TCP-соединению может быть отправлен только один запрос. Прежде чем предыдущий запрос будет выполнен, последующие запросы ставятся в очередь.
- Несколько TCP-соединений
Хотя конвейеризация HTTP/1.1 может поддерживать параллелизм запросов, для браузеров это сложно реализовать, а Chrome, Firefox и т. д. отключают конвейерную обработку. Таким образом, параллелизм запросов версии 1.1 зависит от нескольких TCP-соединений, стоимость установления TCP-соединения высока, и возникнет проблема с медленным запуском. - Избыточные заголовки в текстовом формате
Версия HTTP/1.X представлена в текстовом формате, заголовок несжатый, и каждый запрос будет содержать один и тот же заголовок, такой как cookie, пользовательский агент и т. д. - Клиент должен активно запрашивать
Наступила эра HTTP/2.0
Давайте рассмотрим демонстрацию HTTP/2.0 Hang Zhuangtian. В этой демонстрации загружаются 379 изображений для сравнения производительности HTTP/1.1 и HTTP/2.0.Сравнение производительности HTTP/1.1 и 2.0
Теоретически HTTP/2.0 будет иметь более чем двукратное повышение производительности по сравнению с HTTP/1.1, а в слабой сетевой среде улучшение производительности будет более очевидным. На следующих двух рисунках показано сравнение производительности между быстрым и медленным 3G при настройке сети.
Вас ослепила скорость HTTP/2.0? 2333, тогда официально заговорим о 2.0. Взгляните на некоторые из основных улучшений в 2.0 по сравнению с 1.1.Двоичный слой кадрирования
Ядром повышения производительности HTTP2 является уровень двоичного кадрирования. HTTP2 является бинарным протоколом, он использует бинарный формат для передачи данных вместо текстового формата 1.x.
Посмотрите на картинку! Он ясно выражает разницу между ответом HTTP/1.1 и ответом 2.0. Ответ версии 1.1 представлен в текстовом формате, а ответ версии 2.0 разделен на два фрейма: HEADERS (заголовок) и DATA (полезная нагрузка сообщения) на рисунке — это типы фреймов.Узнайте больше о типах рамокТо есть ответ HTTP делится на два кадра для передачи и кодируется в двоичном формате.Здесь мы упоминаем три концепции.
- Поток: Двунаправленный поток байтов по установленному TCP-соединению, который может передавать одно или несколько сообщений.
- Сообщение: полный HTTP-запрос или ответ, состоящий из одного или нескольких кадров. Кадры для определенного сообщения отправляются в одном потоке, что означает, что HTTP-запрос или ответ могут быть отправлены только в одном потоке.
- Фрейм: основная единица коммуникации.
В TCP-соединении может быть любое количество потоков.
мультиплексирование
Как упоминалось выше, проблема блокировки заголовка строки HTTP/1.1 и множественных TCP-соединений прекрасно решается с помощью мультиплексирования HTTP2. HTTP2 позволяет осуществлять всю связь по одному TCP-соединению, что действительно реализует параллелизм запросов. Давайте посмотрим, как реализован HTTP2:
HTTP2 устанавливает TCP-соединение, и соединение может иметь любое количество потоков (stream), а сообщение разбивается на один или несколько фреймов и передается в потоке. После того, как кадр передан, он снова собирается для формирования полного запроса или ответа. Это делает все запросы или ответы неблокируемыми. Вернемся к демонстрации выше: При открытии консоли видно, что в методе HTTP/1.1 время загрузки следующих картинок в основном застопорилось, задержка означает разницу во времени между завершением установления TCP-соединения и фактической передачей данных. Это блокировка головы очереди, предыдущие запросы не обрабатываются, а последующие ждут в очереди.В этом примере мы можем интуитивно увидеть, что мультиплексирование играет роль оптимизации. Поскольку HTTP2 реализует параллелизм запросов, последующие запросы не должны ждать, и время загрузки, конечно же, намного короче. Сделайте снимок экрана с подробностями загрузки изображения HTTP2, отнимающими много времени (см. более поздние запросы):
Хм? ?什么情况?我们发现后面的很多请求依旧有在排队哎,只是排队的时间相对1.1少了很多。一个TCP连接可以有任意数量的流,也就是同时可以并发任意数量的请求啊,为啥还会排队呢?原因就是请求太多时,浏览器或服务器会受不了,这超出了它的处理能力。流控制帮我们解决了这个问题,流控制会管理数据的传输,允许接收者停止或减少发送的数据量,免得接收方不堪重负。所以请求太多时,还是会存在排队等待的问题,因为不管是客户端或服务器端,能同时处理请求或响应都是有限的。сжатие заголовка
Сжатие заголовков также является изюминкой HTTP2. В версии 1.X заголовок передается в текстовом формате, что обычно добавляет 500-800 байт служебных данных к каждой передаче. Теперь нормально открывать сотни запросов на веб-странице, и некоторые поля заголовка для каждого запроса одинаковы, например, файлы cookie, пользовательский агент и т. д. HTTP2 использует формат сжатия HPACK для сжатия заголовка для этой цели. Сжатие заголовков должно происходить между браузером и сервером:
- поддерживать идентичный статический словарь общих имен заголовков и общих комбинаций имени заголовка и значения
- Поддерживая тот же динамический словарь, вы можете динамически добавлять контент
- Кодировать переданное поле заголовка с помощью статического кодирования Хаффмана.
Статический словарь HTTP2 выглядит так (перехватывается только часть,Полная форма здесь):
Поэтому, когда мы передаем поле заголовка, например, для передачи method:GET, нам нужно только передать значение индекса, соответствующее методу:GET в статическом словаре, что делается одним байтом. Для статических словарей, таких как пользовательский агент и файл cookie, которые имеют только имя заголовка, но не имеют значения, при первой передаче требуется индекс пользовательского агента в статическом словаре и его значение. Значение будет использовать статическое кодирование Хаффмана для уменьшения размера. .После того, как пользовательский агент будет передан в первый раз, браузер и сервер добавят его в свой динамический словарь. Последующие передачи могут передавать индекс, выполняется один байт.
Давайте используем WireShark для захвата пакетов для проверки:
В настоящее время HTTP2 – это все HTTPS-запросы. Информацию о захвате и расшифровке пакетов HTTPS веб-сайтов с помощью WireShark см.здесь.
- Первая передача пользовательского агента и вторая передача пользовательского агента
- Первая прочность на сжатие HPACK
отправка на стороне сервера
Нажатие на стороне сервера позволяет серверу прогнозировать ресурсы, необходимые клиенту, и активно направлять их клиенту.
Например: клиент запрашивает index.html, и сервер может дополнительно продвигать script.js и style.css.
Принцип реализации заключается в том, что когда клиент отправляет запрос страницы, сервер может проанализировать другие ресурсы, которые зависит от страницы, и активно подтолкнут ее к кеше клиента. Когда клиент получает оригинальную веб-страницу, ресурсы, которые необходимо уже в кэше.
Для каждого ресурса, который он хочет отправить, сервер отправляет кадр PUSH_PROMISE, а клиент может отклонить отправку (когда ресурс уже находится в кэше), отправив кадр RST_STREAM. Операция этого шага предшествует родительскому ответу (index.html), и клиент знает, какие ресурсы сервер намеревается протолкнуть, и не будет создавать повторные запросы для этих ресурсов. Когда клиент получает ответ от index.html, script.js и style.css уже находятся в кеше.
Если вы хотите создать сервер HTTP2, рекомендуется использовать узел, это очень просто.Связь
Справочная статья
- Введение в HTTP/2
- HTTP/2 за кулисами
- Введение в технологию сжатия заголовков HTTP/2
- Отладка трафика HTTP/2 с помощью Wireshark
- Каковы основные улучшения HTTP/2.0 по сравнению с 1.0?
- Анализ новых возможностей HTTP/2
Эпилог
Я кратко рассказал о важных улучшениях HTTP2 по сравнению с версией 1.1 и ощутил мощь h2. Есть также некоторые функции, такие как приоритизация потоков, которые не описаны в тексте, если вам интересно, вы можете посмотреть в справочной статье. Если есть какая-то ошибка, пожалуйста, поправьте меня!