Эта статья была впервые опубликована на https://jaychen.cc
Добавить Автора
Напишите что-нибудь про http2.
Предшественником http2 был SPDY, разработанный Google, позже Google передал весь результат в IETF, и IETF стандартизировал SPDY и стал http2. Google также щедро отказался от SPDY в пользу http2. http2 полностью совместим с http/1.x, добавляя на этой основе 4 основных новых функции:
- Бинарное кадрирование
- сжатие заголовка
- Пуш сервера
- мультиплексирование
- Оптимизация
Эти четыре характеристики в основном обсуждаются ниже.
Бинарное кадрирование
http/1.x — это текстовый протокол, а http2 — это полный бинарный протокол, поэтому http2 может придумать так много новых трюков. Бинарный протокол http2 называетсяБинарное кадрирование.
Формат протокола http2 представляет собой фрейм, который аналогичен сообщению данных в TCP.
+--------------------------------------------------------------+ ^
| | |
| Length (24) | |
| | |
| | |
+----------------------+---------------------------------------+ |
| | | +
| | |
| Type (8) | Flag (8) | Frame Header
| | | +
+----+-----------------+---------------------------------------+ |
| | | |
| | | |
| R | Stream Identifier (31) | |
| | | v
+----+---------------------------------------------------------+
| |
| Frame Payload |
| |
+--------------------------------------------------------------+
Кадр состоит из заголовка кадра и полезной нагрузки кадра. Заголовок и тело, которые ранее были в http/1.x, помещаются в полезные данные кадра.
- Поле Type используется для указания того, сохраняет ли полезная нагрузка кадра данные заголовка или данные тела. В дополнение к идентификации заголовка/тела существуют некоторые дополнительные типы кадров.
- Поле «Длина» используется для указания размера данных полезной нагрузки кадра.
- Полезная нагрузка кадра используется для сохранения данных заголовка или тела.
** Идентификатор потока используется для определения того, к какому потоку принадлежит кадр. **Это предложение может показаться немного резким.Чтобы понять роль идентификатора потока здесь, необходимо представить вторую особенность http2 "мультиплексирование".
мультиплексирование
В случае http/1.x каждый http-запрос устанавливает TCP-соединение, что означает, что для каждого запроса требуется трехстороннее рукопожатие. На это будет потрачено много времени и ресурсов, чего нельзя избежать в случае с http/1.x. И браузер будет ограничивать количество одновременных запросов под одним и тем же доменным именем. Поэтому в случае с http/1.x распространенным методом оптимизации является распределение статических ресурсов по разным доменным именам, чтобы обойти ограничение количества одновременно работающих браузеров.
В случае http2 все запросы будут делиться соединением TCP, которое можно сказать, что является признаком Killer HTTP2. : Punch: Из-за этого многие оптимизации от ERA HTTP / 1.x можно выйти на пенсию. Но здесь также есть проблема. Все запросы разделяют TCP-соединение, так как клиент / сервер знает, какие запросы данных определенного кадра (не забывайте, что базовый блок http2 - это кадр)?
Приведенный выше идентификатор потока используется для определения того, какому запросу принадлежит кадр.
Когда клиент одновременно инициирует несколько запросов к серверу, эти запросы будут разбиваться на кадры один за другим, каждый кадр будет передаваться не по порядку в канале TCP, а идентификатор потока одного и того же кадра запроса будет одинаковым. . Когда кадр поступает на сервер, он может быть повторно собран в соответствии с идентификатором потока для получения полного запроса.
сжатие заголовка
В протоколе http/1.x каждый запрос будет содержать данные заголовка, а такая информация, как User-Agent, Accept-Language и другая информация, почти не меняется во время каждого запроса, поэтому эта информация будет меняться во время каждого запроса. . Поэтому в http2 предлагается метод сжатия HPACK для уменьшения трафика, потребляемого заголовком http в каждом запросе.
Принцип сжатия HPACK заключается в следующем:
Клиент и сервер совместно поддерживают «статический словарь» в словаре для каждой строки 3, аналогично следующей таблице.
index | header name | header value |
---|---|---|
2 | :method | GET |
3 | :method | POST |
Когда заголовок запроса содержит:mehtod:GET
, когда клиент отправляет запрос, он напрямую отправляет соответствующее значение индекса в статическое поле, которое здесь равно 2. Когда сервер получает запрос, он ищет имя заголовка и значение заголовка, соответствующее индексу = 2, в статическом словаре и понимает, что клиент инициировал запрос GET.
Клиент и сервер должны поддерживать один и тот же набор статических словарей,здесьУчитывая полный статический словарь, и клиент, и сервер будут соблюдать этот статический словарь.
Вы обнаружите, что некоторые значения заголовков не имеют значения в статическом словаре. Это связано с тем, что значение некоторых полей заголовка, например поля User-Agent, является неопределенным, поэтому стандарт не определяет значение значения заголовка.
Тогда, если вы столкнулись с значением, которое не находится в заголовом значении в статическом словаре, алгоритм HPEACK примет следующий подход:
Предположим, заголовок http-запроса содержитUser-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
, тогда HPACKUser-Agent
значениеКодирование Хаффмана, затем найдите в статическом словареUser-Agent
Индекс 58, то клиент будетUser-Agent
Значение индексаUser-Agent
Кодированное по Хаффману значение, соответствующее значению, отправляется на сервер.
User-Agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
会被转换陈下面的 kv 值发送给服务端:
58 : Huffman('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36')
После того, как сервер получит запрос,User-Agent
и значения в кодировке Хаффмана добавляются к статическому словарю, и эти добавленные строки называются «динамическими словарями».
index | header name | header value |
---|---|---|
2 | :method | GET |
3 | :method | POST |
... | .... | ..... |
62 | User-Agent | Huffman('header value') |
Когда клиент отправляет запрос, он также добавит строку в таблицу статического словаря, поддерживаемую им самим, чтобы таблица словаря, поддерживаемая субклиентом и сервером, была согласованной. Если последующий запрос клиенту необходимо выполнитьUser-Agent
поле, просто отправьте 62.
HTTP2 Ситуация полностью отличается, все запросы завершены в соединении TCP.
Пуш сервера
Серверная отправка означает, что сервер активно отправляет данные клиенту.
Например, index.html имеет следующий код
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>hello world</h1>
<img src="something.png">
</body>
</html>
В обычных условиях для отображения страницы требуется 3 запроса:
- Сделать 1 запрос на страницу index.html
- Проанализируйте страницу index.html, чтобы найти ресурсы style.css и something.png, и инициируйте 2 запроса для получения ресурсов.
Если на сервере настроен серверный push, ситуация становится следующей:
- Запрос браузера index.html.
- Сервер обнаруживает, что index.html, запрошенный браузером, содержит ресурсы style.css и something.png, поэтому три ресурса index.html, style.css и something.png напрямую возвращаются браузеру.
Таким образом, серверу и браузеру нужно только один раз связаться, чтобы получить все ресурсы.
с http/1.x на http2
Целью http2 является оптимизация некоторых проблем с производительностью http/1.x, поэтому, когда появится http2, многие методы оптимизации для http/1.x станут недоступны. И на какие проблемы стоит обратить внимание при использовании http2?
https
Вражда между https и http2 интересна. Когда Google разрабатывает SPDY, обязательно использовать https.Согласно причинам, http2 на основе SPDY также должен быть обязательным для https.Однако из-за препятствий сообщества http2 не может использовать протокол https. Однако и chrome, и firefox заявили, что они будут разрабатывать http2 только на основе https, поэтому это в основном означает, что предпосылкой использования http2 должен быть https.
Ненужная оптимизация
В эпоху HTTP / 1.x, чтобы уменьшить количество запросов браузера / увеличить количество параллельных браузеров, обычно используются следующие методы для оптимизации:
- Фрагментация доменного имени: статическое распределение ресурсов под разными доменными именами, чтобы вырваться из браузера Единого доменного имени одновременно. (Упоминается в мультиплексе)
- Слияние файлов. Внешний интерфейс обычно объединяет несколько небольших файлов в один большой, чтобы браузер мог получать ресурсы только одним запросом. Но у этого есть недостаток: если изменена только небольшая часть файла, нужно переслать все содержимое.
Вышеупомянутые методы оптимизации не нужны в случае http2.