Разберитесь с HTTP, HTTPS и HTTP2 за полчаса

HTTP

Эта статья разрешает эксклюзивное использование общедоступной учетной записи сообщества разработчиков Nuggets, включая, помимо прочего, редактирование, пометку оригинальности и другие права.

В этой статье мы попытаемся использовать простой для понимания способ рассказать читателю о знании HTTP.

Кроме того, рекомендуется использовать инструменты разработчика Chrome для практики при изучении HTTP, которые могут помочь вам глубже понять.

在这里插入图片描述

(Эта картинка была найдена в Интернете, захвачена и удалена)

Обзор HTTP

Протокол передачи гипертекста HTTP — это протокол прикладного уровня, расположенный в архитектуре TCP/IP, который является основой для передачи данных во Всемирной паутине.

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

<协议>://<域名>:<端口>/<路径>

Общая форма URL обычно указана выше (http://test.com/index.html), чаще всего используется протокол HTTP. Порт HTTP по умолчанию — 80, который обычно можно не указывать.

在这里插入图片描述

HTTP/1.1

В настоящее время наиболее широко используется версия HTTP/1.1, как правило, версия без специального указания относится к HTTP/1.1.

Процесс установления HTTP-соединения

Давайте рассмотрим процесс получения HTML-страницы после ввода URL-адреса в браузере.

  1. пройти первымСистема доменных имен, DNSЗапрос переводит доменное имя в IP-адрес. вскореtest.comПеревести в221.239.100.30этот процесс.
  2. TCP-соединение устанавливается через трехстороннее рукопожатие (подробнее об этом позже).
  3. Сделайте HTTP-запрос.
  4. Целевой сервер получает HTTP-запрос и обрабатывает его.
  5. Целевой сервер в браузер отправляет ответ HTTP.
  6. Браузер анализирует и отображает страницу.

RTT на рисунке ниже — это задержка приема-передачи (время приема-передачи: задержка приема-передачи. Указывает общую задержку с момента, когда отправитель отправляет данные, до момента, когда отправитель получает подтверждение от получателя).

在这里插入图片描述

Процесс разрыва HTTP-соединения

Все HTTP-клиенты (браузеры) и серверы могут закрыть TCP-соединения в любое время. Соединение обычно закрывается в конце сообщения, но также может быть закрыто в середине строки заголовка или в любом другом месте в случае ошибки.

Трехстороннее рукопожатие TCP и четырехсторонняя волна

Поскольку HTTP основан на TCP, я намерен дополнить здесь процесс установления и разрыва TCP-соединений.

Во-первых, нам нужно понять поля и флаги некоторых сегментов TCP:

  1. 32-битное поле порядкового номера и поле номера подтверждения, каждый байт потока байтов TCP нумеруется последовательно. Номер подтверждения — это порядковый номер следующего байта, который получатель ожидает получить от другой стороны.
  2. Бит флага ACK, используемый для указания того, что значение в поле подтверждения является допустимым. ACK=1 является допустимым, ACK=0 недействительным.
  3. Флаг SYN используется для установления соединения, когда SYN равен 1, это означает, что это запрос на установление соединения.
  4. Флаг FIN используется для удаления соединения, когда FIN равен 1, это означает, что данные отправителя были отправлены и соединение необходимо разорвать.

在这里插入图片描述

Трехстороннее рукопожатие TCP для установления соединения

Стандарт TCP предусматривает, что сегмент ACK может иметь данные, но ему не нужно потреблять порядковый номер, если он не несет данных.

  1. Клиент отправляет сегмент TCP, который не содержит данных прикладного уровня, SYN заголовка устанавливается равным 1, а начальный порядковый номер (обычно 0) выбирается случайным образом и помещается в поле порядкового номера сегмента TCP. (Когда SYN равен 1, данные не могут передаваться, но должен использоваться порядковый номер)
  2. После того, как сегмент TCP достигает узла сервера, сервер извлекает сегмент и выделяет буферы и переменные для соединения TCP. Затем отправьте сегмент ACK (без данных прикладного уровня) клиенту, который разрешает соединение. Заголовок этого сегмента содержит 4 части информации: ACK установлен в 1, SYN установлен в 1, поле номера подтверждения установлено в серийный номер клиента + 1, его начальный серийный номер выбирается случайным образом (обычно 0).
  3. После получения сегмента ответа TCP от сервера клиент также выделяет буферы и переменные для соединения TCP и отправляет сегмент ACK на сервер. Этот сегмент помещает порядковый номер на стороне сервера + 1 в поле номера подтверждения и используется для ответа на сегмент, к которому сервер разрешает соединение.Поскольку соединение установлено, SYN устанавливается равным 0. На заключительном этапе сегмент может передавать данные от клиента к серверу. И для каждого последующего сегмента SYN устанавливается в 0.

Следующий рисунок является конкретным примером:

在这里插入图片描述

(Этот снимок экрана является снимком экрана TCP-сегмента, который я захватил с помощью инструмента захвата пакетов Wireshark).

TCP помахал четыре раза, чтобы разорвать соединение

Даже если сегмент FIN не содержит данных, используется порядковый номер.

  1. Клиент отправляет сегмент с FIN, установленным на 1.
  2. Сервер отправляет обратно сегмент подтверждения.
  3. Сервер отправляет сегмент с FIN, установленным на 1.
  4. Клиент отправляет обратно сегмент подтверждения.

Почему TCP колеблется четыре раза вместо трех?

  1. Когда A отправляет сообщение FIN в B, это означает, что A больше не отправляет сообщения, но все еще может получать сообщения.
  2. У B все еще могут быть данные для отправки, поэтому сначала отправьте сообщение ACK, сообщая A: «Я понимаю ваш запрос на отключение». Таким образом, A не будет продолжать отправлять запрос на отключение (то есть сообщение FIN), потому что он не получает ответа.
  3. После того, как B обработает данные, он отправляет сообщение FIN в A, а затем входит в стадию LAST_ACK (ожидание тайм-аута).
  4. A отправляет сообщение ACK на B, и обе стороны отключаются.

Использованная литература:

Формат HTTP-сообщения

HTTP-сообщение состоит из строки запроса, заголовка и тела объекта, которые разделены CRLF (возврат каретки).

Примечание. Сущность включает в себя заголовок (также называемый заголовком сущности) и тело сущности, а sp — это пробел..

在这里插入图片描述

Строка запроса и заголовок состоят из текста ASCII, а тело объекта является необязательным и может быть пустым или произвольным двоичным данными.

Формат сообщения запроса и сообщения ответа в основном одинаков.

Формат сообщения запроса:

<method> <request-URL> <version>
<headers>
<entity-body>

Формат ответного сообщения:

<version> <status> <reason-phrase>
<headers>
<entity-body>

Запрос или ответное сообщение состоит из следующих полей:

  1. Метод запроса, действие, которое клиент хочет, чтобы сервер выполнил над ресурсом.
  2. URL-адрес запроса, который называет запрошенный ресурс.
  3. Версия протокола, версия HTTP, используемая сообщением.
  4. Код состояния, эти три цифры описывают, что произошло во время запроса.
  5. Reason Phrase, удобочитаемая версия числового кода состояния (например, OK, за которым следует 200 в приведенном выше примере ответа, который обычно лучше записывать в спецификации).
  6. Заголовок, который может иметь ноль или более заголовков.
  7. Тело объекта, которое может быть пустым или содержать произвольные двоичные данные.

Пример HTTP-запроса:

GET /2.app.js HTTP/1.1
Host: 118.190.217.8:3389
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: */*
Referer: http://118.190.217.8:3389/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

Пример HTTP-ответа:

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sat, 07 Mar 2020 03:52:30 GMT
ETag: W/"253e-170b31f7de7"
Content-Type: application/javascript; charset=UTF-8
Vary: Accept-Encoding
Content-Encoding: gzip
Date: Fri, 15 May 2020 05:38:05 GMT
Connection: keep-alive
Transfer-Encoding: chunked

метод

метод описывать
GET Получить документ с сервера
HEAD Получить только заголовок документа с сервера
POST Отправка данных на сервер, которые необходимо обработать
PUT Сохраните запрошенную часть данных на сервере
TRACE Отслеживание пакетов, которые могут быть отправлены на сервер через прокси-сервер
OPTIONS Решите, какие методы могут выполняться на сервере
DELETE Удалить документ с сервера
ПОЛУЧИТЬ и ГОЛОВА

где GET и HEAD называются безопасными методами, потому что они идемпотентны (если запрос имеет один и тот же результат независимо от того, сколько раз он выполняется, этот запросидемпотент), как и POST, не является идемпотентным.

Метод HEAD аналогичен методу GET, но сервер возвращает только заголовок в ответе. Это позволяет клиенту проверять заголовок ресурса, не получая фактический ресурс. С HEAD вы можете:

  1. Знайте, что происходит с ресурсом, не приобретая его.
  2. Посмотрите, существует ли объект, взглянув на код состояния ответа.
  3. Узнайте, был ли изменен тестовый ресурс, просмотрев заголовок.

Разработчик сервера должен убедиться, что возвращаемые заголовки точно такие же, как и в ответе на запрос GET. В соответствии со спецификацией HTTP/1.1 должен быть реализован метод HEAD.

PUT

В отличие от метода GET, который считывает документы с сервера, метод PUT записывает документы на сервер. Семантика метода PUT заключается в том, чтобы сервер использовал тело запроса для создания нового документа, названного по запрошенному URL-адресу. Если этот документ уже существует, перезапишите его.

POST

Метод POST обычно используется для отправки данных формы на сервер.

TRACE

Когда клиент инициирует запрос, запрос может пройти через маршрутизаторы, брандмауэры, прокси, шлюзы и т. д. Каждый промежуточный узел может изменить исходный HTTP-запрос, а метод TRACE позволяет клиенту увидеть, как он выглядит, когда он, наконец, сделает запрос.

Запрос TRACE инициирует диагностику «петли» на целевом сервере. Сервер на последней остановке поездки возвратит ответ TRACE с исходным сообщением запроса, которое он получил в теле ответа. Это позволяет клиенту увидеть, было ли повреждено или изменено исходное сообщение в цепочке запросов/ответов всех промежуточных HTTP-приложений.

在这里插入图片描述

Метод TRACE в основном используется в диагностических целях, чтобы убедиться, что запрос проходит по цепочке запрос/ответ, как предполагалось. Это также инструмент для просмотра влияния прокси и других приложений на запросы пользователей. Запрос TRACE не может иметь часть тела сущности. Часть тела ответа TRACE содержит точную копию запроса, полученного сервером ответов.

OPTIONS

Метод OPTIONS запрашивает веб-сервер, чтобы сообщить ему о различных функциях, которые он поддерживает.

DELETE

Метод DELETE указывает серверу удалить ресурс, указанный URL-адресом запроса.

код состояния

общий охват определенный диапазон Классификация
100~199 100~101 уведомление о сообщении
200~299 200~206 успех
300~399 300~305 перенаправить
400~499 400~415 ошибка клиента
500~599 500~505 Ошибка сервера
300~399 код состояния перенаправления

Код состояния перенаправления либо сообщает клиенту использовать альтернативное расположение для доступа к интересующему его ресурсу, либо предоставляет альтернативный ответ вместо содержимого ресурса. Если ресурс был перемещен, код состояния перенаправления и необязательный заголовок Location могут быть отправлены, чтобы сообщить клиенту, что ресурс был перемещен и где его найти сейчас. Таким образом, браузер может прозрачно перейти в новое место, не беспокоя пользователя.

400~499 Код состояния ошибки клиента

Иногда клиент отправляет что-то, что сервер не может обработать, например, неправильно сформированное сообщение запроса, несуществующий URL-адрес.

500~599 Код состояния ошибки сервера

Иногда клиент отправляет правильный запрос, а сам сервер дает сбой.

столица

Заголовки и методы работают вместе, чтобы определить, что могут делать клиент и сервер.

класс заголовка:

  1. Общий заголовок, который может появляться в сообщениях запроса или ответа.
  2. Заголовок запроса, который предоставляет дополнительную информацию о запросе.
  3. Заголовки ответа, которые предоставляют дополнительную информацию об ответе.
  4. Заголовок сущности, описывающий длину и содержимое тела или самого ресурса.
  5. Заголовки расширения, новые заголовки, не определенные в спецификации.
общий заголовок

Некоторые заголовки предоставляют самую основную информацию о сообщении, они называются общими заголовками. Вот некоторые общие общие заголовки:

在这里插入图片描述

заголовок запроса

Заголовок запроса является осмысленным заголовком только в сообщении запроса, который используется для описания деталей запроса. Вот некоторые распространенные заголовки запросов:

在这里插入图片描述

заголовок ответа

Заголовки ответов позволяют серверу предоставлять клиенту дополнительную информацию.

заголовок сущности

Заголовок объекта предоставляет обширную информацию о объекте и его содержимом, от информации о типе объекта до различных допустимых методов запроса, которые можно использовать для ресурса.

НапримерЗаголовок контента, который предоставляет конкретную информацию о содержимом объекта, указав его тип, размер и другую полезную информацию, необходимую для его обработки. Кроме того, общий заголовок кэша описывает, как и когда кэшировать.Заголовок кэша сущностейПредоставляет информацию о кэшированных сущностях.

在这里插入图片描述

оптимизация производительности

1. Уменьшите HTTP-запросы

Каждый раз, когда инициируется HTTP-запрос, для установления TCP-соединения требуется трехстороннее рукопожатие. Если соединение используется только для обмена небольшим объемом данных, этот процесс серьезно снизит производительность HTTP. Таким образом, мы можем объединить несколько небольших файлов в один большой файл, тем самым уменьшив количество HTTP-запросов.

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

2. Используйте CDN для статических ресурсов

Сеть доставки контента (CDN) — это группа веб-серверов, распределенных в разных географических точках. Все мы знаем, что чем дальше сервер от пользователя, тем выше задержка. CDN предназначены для решения этой проблемы, развертывая серверы в нескольких местах, приближая пользователей к серверу, тем самым сокращая время запросов.

3. Эффективно используйте кеш

Чтобы пользователям не приходилось запрашивать файлы каждый раз, когда они посещают веб-сайт, мы можем контролировать это поведение, добавив заголовок Expires. Expires устанавливает время, пока до этого времени браузер не будет запрашивать файл, а будет напрямую использовать кеш.

Но это создаст проблему, что делать при обновлении файла? Как я могу сказать браузеру повторно запросить файл?

Обновляя адрес ссылки на ресурс, указанный на странице, браузер может активно отказаться от кеша и загрузить новый ресурс.

Конкретный подход заключается в том, чтобы связать изменение URL-адреса ресурса и содержимого файла, то есть только изменения содержимого файла могут привести к изменению соответствующего URL-адреса для реализации точного управления кешем на уровне файла. Что связано с содержимым файла? Мы будем очень естественными.Дайджест данных в алгоритмСводная информация получается для файла, и сводная информация соответствует содержимому файла один за другим, и существует основа управления кэшем, которая может быть точной для детализации одного файла.

Использованная литература:

4. Сжать файл

Сжатие файлов может сократить время загрузки файлов и улучшить взаимодействие с пользователем.

Гжип, безусловно, самый популярный и эффективный метод сжатия. Это может быть включено, добавив флаг GZIP в заголовок кодирования ACCECT в заголовках HTTP-запроса. Конечно, сервер также должен поддерживать эту функцию.

Например, размер файла app.js, созданного после сборки проекта, который я разработал с помощью Vue, составляет 1,4 МБ, а после сжатия gzip — всего 573 КБ, что уменьшает размер почти на 60%.

5. Точное кеширование файлов с максимальным возрастом и без кеша

Общий заголовок сообщенияCache-ControlЕсть два варианта:

  1. max-age: установить максимальный период хранения кеша, по истечении которого кеш считается просроченным (в секундах). До этого времени браузер не будет выдавать новый запрос на чтение файла, а будет напрямую использовать кеш.
  2. no-cache: Указание без кэширования означает, что клиент может кэшировать ресурс и должен повторно проверять его достоверность каждый раз, когда используется кэшированный ресурс.

Мы можем установить очень большое время кэширования для тех статических ресурсов, которые долго не меняются, например, установить кэширование на один год.

потомindex.htmlфайл установлен наno-cache. Таким образом, каждый раз, когда вы посещаете веб-сайт, браузер будет спрашиватьindex.htmlЕсть ли обновление, если нет, используйте староеindex.htmlдокумент. Если есть обновление, прочитайте новоеindex.htmlдокумент. при загрузке новыхindex.htmlОн также будет загружен с новыми ресурсами URL.

Напримерindex.htmlпервоначально процитированоa.jsа такжеb.js, который теперь обновлен доa.jsа такжеc.js. он будет только загружатьсяc.jsдокумент.

Подробнее см.webpack + express обеспечивает точное кэширование файлов.

HTTPS

HTTPS — самая популярная форма безопасности HTTP, разработанная Netscape и поддерживаемая всеми основными браузерами и серверами. При использовании HTTPS все данные HTTP-запросов и ответов шифруются перед отправкой. Шифрование может использовать SSL или TLS.

在这里插入图片描述

Протокол SSL/TLS работает по протоколу HTTP, для приложений верхнего уровня исходный поток данных отправки/получения остается неизменным, что хорошо совместимо со старым протоколом HTTP. Поскольку разница между SSL/TLS невелика, SSL используется единообразно ниже.

Чтобы понять, почему HTTPS безопасен, мы должны продолжать понимать следующие концепции:Алгоритм шифрования,Алгоритм дайджеста,цифровой подписиа такжеЦифровой сертификат.

Алгоритм шифрования

Криптосистема с симметричным ключом

Криптосистема с симметричным ключом, то есть ключ шифрования и ключ дешифрования используют одну и ту же криптосистему. Одним из недостатков технологии шифрования с симметричным ключом является то, что отправитель и получатель должны иметь общий ключ, прежде чем говорить, поэтому это не очень безопасно.

криптосистема с открытым ключом

Криптосистемы с открытым ключом используют разные ключи шифрования и ключи дешифрования. Есть две основные причины появления криптосистем с открытым ключом: одна — проблема распределения ключей в криптосистемах с симметричным ключом, а другая — потребность в цифровых подписях.

В криптосистеме с открытым ключом ключ шифрования является открытым, ключ дешифрования должен храниться в секрете, а алгоритм шифрования и алгоритм дешифрования также являются общедоступными.

Шифрование и дешифрование криптосистемы с открытым ключом имеет следующие характеристики:

  1. генератор пары ключейСгенерируйте пару ключей для получателя B, а именно ключ шифрования PK и ключ дешифрования SK.
  2. Отправитель A использует открытый ключ PK B в качестве ключа шифрования для шифрования информации, а B расшифровывает ее с помощью ключа дешифрования SK после ее получения.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uWP5p7So-1589532545350)(../imgs/is3.png)]

При использовании симметричного ключа, поскольку обе стороны используют один и тот же ключ, по коммуникационному каналу может осуществляться двусторонняя безопасная связь «один к одному», и обе стороны могут использовать один и тот же ключ для шифрования и дешифрования.

При использовании открытых ключей это может быть многосторонний односторонний безопасный канал по каналу связи. То есть несколько человек могут владеть открытым ключом B, но только B может его расшифровать.

Алгоритм дайджеста

Основная особенность алгоритма дайджеста заключается в том, что для процесса шифрования не требуется ключ, и зашифрованные данные не могут быть расшифрованы.В настоящее время только алгоритм CRC32 может быть расшифрован в обратном порядке.Только когда одни и те же данные открытого текста вводятся через тот же Алгоритм дайджеста сообщения позволяет получить тот же зашифрованный текст.

цифровой подписи

Сообщение подписывается с помощью системы шифрования, чтобы указать, кто написал сообщение, и чтобы доказать, что сообщение не было подделано.Этот метод называетсяцифровой подписи.

Цифровая подпись — это специальный код проверки шифрования, прикрепленный к сообщению. Преимущества использования цифровых подписей:

  1. Подпись доказывает, что автор написал сообщение. Только у автора будет самый конфиденциальный закрытый ключ, поэтому только автор может вычислить эти контрольные суммы.
  2. Подпись предотвращает подделку сообщения, и если кто-то изменит сообщение в пути, контрольные суммы больше не будут совпадать.

Цифровые подписи обычно генерируются с использованием методов асимметричного открытого ключа.

在这里插入图片描述

Глядя на рисунок выше, любой может использовать открытый ключ PK пользователя A для выполнения операции E над зашифрованным текстом, чтобы получить открытый текст, отправленный пользователем A. Видно, что этот вид связи предназначен не для конфиденциальности, а для подписания и проверки подписи, то есть для подтверждения того, что эта информация отправлена ​​​​А (сообщение, зашифрованное ключом А, может быть правильно расшифровано только с использованием открытого ключа А). ). Однако описанный выше процесс только подписывает сообщение, а само сообщение X не хранится в секрете, поэтому метод, показанный на рисунке ниже, используется для одновременной реализации секретной связи и цифровой подписи.

在这里插入图片描述

Цифровой сертификат

Если вы хотите посетить веб-сайт, как вы гарантируете, что открытый ключ, предоставленный вам другой стороной, является открытым ключом веб-сайта, который вы хотите посетить, и не подделан посредником?

Появление цифровых сертификатов должно решить эту проблему.Он выдается центром сертификации цифровых сертификатов для подтверждения личности владельца открытого ключа. Другими словами, роль цифрового сертификата эквивалентна удостоверению личности человека, что доказывает, что Чжан Сан — это Чжан Сан, а не кто-то другой.

Цифровой сертификат обычно содержит следующее содержимое:

  1. имя объекта (человек, сервер, организация и т. д.);
  2. Срок действия;
  3. Издатель сертификата (кто ручается за сертификат);
  4. Цифровая подпись от эмитента сертификата;
  5. открытый ключ объекта;
  6. Описательная информация об объекте и используемом алгоритме подписи.

Любой может создать цифровой сертификат, но важно, кто поручится за это.

Процесс вычисления цифровой подписи цифрового сертификата:

  1. Сводка рассчитывается на содержание цифрового сертификата с резюме алгоритма;
  2. Цифровая подпись получается путем шифрования дайджеста закрытым ключом цифрового сертификата.

在这里插入图片描述

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

Поскольку открытый ключ цифрового сертификата является открытым, любой может использовать открытый ключ для расшифровки дайджеста цифровой подписи цифрового сертификата, а затем использовать тот же алгоритм дайджеста для вычисления дайджеста содержимого сертификата. , если содержимое соответствует, это означает, что сертификат не был подделан и ему можно доверять.

Этот процесс основан на открытом ключе, полученном от признанного центра сертификации, поэтому это безопасный способ.

在这里插入图片描述

Процесс установления HTTPS-соединения

Процесс установления соединения HTTPS аналогичен HTTP, разница в том, что запросы HTTP (порт 80 по умолчанию) могут быть инициированы до тех пор, пока установлено соединение TCP, в то время как HTTPS (порт 443 по умолчанию) должен пройти рукопожатие протокола SSL после установления соединения. TCP-соединение установлено, сделайте запрос.

在这里插入图片描述

在这里插入图片描述

Я знаю, что найдутся люди, которых не устроит упрощенный процесс рукопожатия SSL, поэтому я нашел статьюПодробное объяснение процесса рукопожатия SSL/TLS, в этой статье очень подробно объясняется каждый шаг SSL-рукопожатия. Заинтересованным студентам рекомендуется ознакомиться.

HTTP/2

HTTP/2 — это расширение HTTP/1.x, а не замена. Таким образом, семантика HTTP остается неизменной, предоставляемые функции остаются неизменными, а основные концепции, такие как методы HTTP, коды состояния, URL-адреса и поля заголовков, остаются неизменными.

Причина увеличения основной версии до 2.0 в основном состоит в том, что она изменяет способ обмена данными между клиентами и серверами. HTTP 2.0 добавляет новый уровень двоичных данных кадрирования, который не совместим с предыдущими серверами и клиентами HTTP 1.x — так называемый 2.0.

Процесс установления соединения HTTP/2

Текущая реализация HTTP/2 в основных браузерах основана на SSL/TLS, то есть все веб-сайты, использующие HTTP/2, являются протоколом HTTPS, поэтому в этой статье обсуждается только процесс установления соединения HTTP/2 на основе SSL/TLS.

Процесс установления соединения HTTP/2 на основе SSL/TLS аналогичен процессу HTTPS. Во время согласования рукопожатия SSL/TLS клиент устанавливает расширение ALPN (согласование протокола прикладного уровня) в сообщении ClientHello, чтобы указать, что он ожидает использования протокола HTTP/2, и сервер отвечает таким же образом. Таким образом, HTTP/2 устанавливается во время согласования рукопожатия SSL/TLS.

Проблемы с HTTP/1.1

1. Блокировка начала очереди

В процессе ответа на HTTP-запрос, если возникает определенная ситуация, из-за которой ответ не может быть завершен, все последующие запросы будут постоянно блокироваться, такая ситуация называется блокировкой заголовка строки.

2. Неэффективное использование TCP

из-заМеханизм медленного запуска TCP, что приводит к низкой скорости передачи для каждого TCP-подключения в начале и постепенно достигает «подходящей» скорости после обработки нескольких запросов. Эта ситуация является катастрофой для HTTP-запросов, требующих очень мало данных.

3. Раздутые заголовки сообщений

Заголовок HTTP/1.1 не может быть сжат.В сочетании с наличием файлов cookie размер заголовка часто превышает размер данных запроса.

4. Ограниченные настройки приоритета

HTTP/1.1 не может назначать приоритет важным ресурсам, каждый HTTP-запрос обрабатывается одинаково.

Прежде чем перейти к новым возможностям HTTP/2, имеет смысл перечислить проблемы с HTTP/1.1. Потому что некоторые из новых функций HTTP/2 созданы для решения некоторых из вышеперечисленных проблем.

Двоичный слой кадрирования

HTTP/2 — это протокол на основе кадров. Фреймирование используется для инкапсуляции важной информации, чтобы синтаксический анализатор протокола мог легко читать, анализировать и восстанавливать информацию.

А HTTP/1.1 имеет текстовые разделители. Синтаксический анализ HTTP/1.1 не требует высоких технологий, но часто выполняется медленно и подвержено ошибкам. Вам нужно продолжать чтение в байтах, пока вы не нажмете разделитель CRLF, а также учитывать неуправляемых клиентов, которые будут просто отправлять LF.

При разборе запросов или ответов HTTP/1.1 также возникают следующие проблемы:

  1. Одновременно может обрабатываться только один запрос или ответ, и синтаксический анализ нельзя остановить, пока он не будет завершен.
  2. Невозможно предсказать, сколько памяти потребуется для синтаксического анализа.

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

在这里插入图片描述

каркасная конструкция

 +-----------------------------------------------+
 |                 Length (24)                   |
 +---------------+---------------+---------------+
 |   Type (8)    |   Flags (8)   |
 +-+-------------+---------------+-------------------------------+
 |R|                 Stream Identifier (31)                      |
 +=+=============================================================+
 |                   Frame Payload (0...)                      ...
 +---------------------------------------------------------------+
имя длина описывать
Length 3 байта Указывает длину полезной нагрузки кадра в диапазоне от (2 в 14-й степени) до (2 в 24-й степени - 1). (2 в 14-й степени) 16384 байта — максимальный размер кадра по умолчанию, если требуется кадр большего размера, его необходимо установить в кадре НАСТРОЙКИ.
Type 1 байт Текущий тип кадра (см. таблицу ниже)
Flags 1 байт Идентификация конкретного типа кадра
R 1 человек зарезервированный бит, не устанавливайте, иначе могут быть серьезные последствия
Stream Identifier 31 бит Уникальный идентификатор для каждого потока
Frame Payload переменная длина Фактическое содержимое кадра, длина задается в поле Длина

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

тип рамы

имя ID описывать
DATA 0x0 Основное содержание транспортного потока
HEADERS 0x1 Содержит заголовки HTTP и необязательные параметры приоритета.
PRIORITY 0x2 Указать или изменить приоритет и зависимости потока
RST_STREAM 0x3 Разрешить остановку потока на одном конце (обычно из-за ошибки)
SETTINGS 0x4 Договориться о параметрах уровня связи
PUSH_PROMISE 0x5 Подскажите клиенту, что сервер хочет что-то нажать
PING 0x6 Проверить доступность соединения и задержку приема-передачи (RTT)
GOAWAY 0x7 Сообщите другой стороне, что текущая сторона закончилась
WINDOW_UPDATE 0x8 Согласуйте, сколько байтов получит один конец (для управления потоком)
CONTINUATION 0x9 для расширения модуля HEADERS

мультиплексирование

В HTTP/1.1, если клиент хочет отправить несколько одновременных запросов, он должен использовать несколько соединений TCP.

Уровень двоичного кадрирования HTTP/2 снимает это ограничение, и все запросы и ответы отправляются по одному и тому же TCP-соединению: клиент и сервер разбивают HTTP-сообщение на несколько кадров, затем отправляют их не по порядку и, наконец, в другом конце. затем повторно собирается в соответствии с идентификатором потока.

Этот механизм обеспечивает огромный прирост производительности для HTTP, потому что:

  • Запросы можно отправлять параллельно и чередовать, не влияя друг на друга;
  • Ответы можно отправлять параллельно и чередовать, не мешая друг другу;
  • Отправляйте несколько запросов и ответов параллельно, используя только одно соединение;
  • Устраните ненужные задержки, сократив тем самым время загрузки страницы;
  • Больше никаких усилий по обходу ограничений HTTP 1.x;

在这里插入图片描述

поток

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

После того, как соединение HTTP/2 между клиентом и сервером установлено, новый поток запускается путем отправки кадра HEADERS. Кадр ПРОДОЛЖЕНИЯ также может быть отправлен, если заголовок должен охватывать несколько кадров. Кадр HEADERS может исходить из запроса или ответа. Когда запускаются последующие потоки, отправляется новый кадр HEADERS с увеличенным идентификатором потока.

Информация

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

Сообщение состоит как минимум из кадра HEADERS (который инициализирует поток) и может дополнительно содержать кадры CONTINUATION и DATA, а также другие кадры HEADERS.

在这里插入图片描述

Части запроса и ответа HTTP/1.1 разделены на две части: заголовок сообщения и тело сообщения; части запроса и ответа HTTP/2 разделены на кадры HEADERS и кадры DATA.

приоритет

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

Через кадры HEADERS и PRIORITY клиент может явно сообщить серверу, что ему нужно и в каком порядке ему нужны эти ресурсы. В частности, сервер может управлять распределением ресурсов (ЦП, памяти, полосы пропускания) в соответствии с приоритетом потока, и после того, как данные ответа готовы, кадр с наивысшим приоритетом отправляется клиенту первым.

управление потоком

Передача нескольких потоков данных по одному TCP-соединению означает совместное использование полосы пропускания. Приоритизация потоков данных помогает упорядоченной доставке, но одного приоритета недостаточно для определения распределения ресурсов между несколькими потоками или несколькими соединениями.

Чтобы решить эту проблему, HTTP/2 предоставляет простой механизм управления потоками данных и соединениями:

  • Управление потоком выполняется для каждого перехода, а не для сквозного управления;
  • Управление потоком основано на кадре WINDOW_UPDATE, то есть приемник вещает, сколько байтов потока данных он готов принять, и сколько байтов принять за все соединение;
  • Размер окна управления потоком обновляется через кадр WINDOW_UPDATE, в этом поле указывается идентификатор потока и значение приращения размера окна;
  • Управление потоком является направленным, то есть получатель может установить любой размер окна для каждого потока или даже всего соединения в соответствии со своей ситуацией;
  • Управление потоком может быть отключено получателем, как для отдельных потоков, так и для всего соединения.

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

пуш сервера

Новая мощная функция, добавленная в HTTP/2, заключается в том, что сервер может отправлять несколько ответов на запрос клиента. Другими словами, в дополнение к ответу на первоначальный запрос сервер может передавать дополнительные ресурсы клиенту без явного запроса клиента.

在这里插入图片描述

Зачем нужен такой механизм? Типичное веб-приложение состоит из десятков ресурсов, и клиенту необходимо анализировать документы, предоставленные сервером, чтобы найти их один за другим. Так почему бы не позволить серверу заранее передать эти ресурсы клиенту, сократив тем самым дополнительную задержку? Сервер уже знает, какой ресурс клиент собирается запросить следующим, и здесь на помощь приходит проталкивание сервером.

В качестве альтернативы клиент может отклонить отправку сервера.

сжатие заголовка

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

Например, есть следующие два запроса:

:authority: unpkg.zhimg.com
:method: GET
:path: /za-js-sdk@2.16.0/dist/zap.js
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cache-control: no-cache
pragma: no-cache
referer: https://www.zhihu.com/
sec-fetch-dest: script
sec-fetch-mode: no-cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
:authority: zz.bdstatic.com
:method: GET
:path: /linksubmit/push.js
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cache-control: no-cache
pragma: no-cache
referer: https://www.zhihu.com/
sec-fetch-dest: script
sec-fetch-mode: no-cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36

Как видно из двух приведенных выше запросов, много данных дублируется. Если вы можете хранить один и тот же заголовок и отправлять между ними только разные части, вы можете сэкономить много трафика и ускорить время запроса.

HTTP/2 использует «таблицу заголовков» на стороне клиента и сервера для отслеживания и хранения ранее отправленных пар ключ-значение и больше не отправляет каждый запрос и ответ для одних и тех же данных.

Давайте рассмотрим упрощенный пример, предполагая, что клиент отправляет следующие заголовки запроса по порядку:

Header1:foo
Header2:bar
Header3:bat

Когда клиент отправляет запрос, он создает таблицу на основе значений заголовка:

показатель имя заголовка стоимость
62 Header1 foo
63 Header2 bar
64 Header3 bat

Если сервер получит запрос, он создаст таблицу, как обычно. Когда клиент отправляет следующий запрос, если заголовки совпадают, он может напрямую отправить блок заголовка следующим образом:

62 63 64

Сервер будет искать ранее созданную таблицу и восстанавливать числа до полного заголовка, соответствующего индексу.

оптимизация производительности

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

Разъединить ресурсы

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

Отменить разделение домена

Причина отмены разделения доменных имен та же, что и выше: в одном TCP-соединении не может быть отправлено никакого количества HTTP-запросов, поэтому нет необходимости использовать несколько доменных имен, чтобы превысить лимит TCP-соединений браузера.

использованная литература

Чтобы увидеть больше статей, следите за обновлениями