Блог об it, программировании и интернет-маркетинге

Делюсь наблюдениями и личным опытом в области программирования и интернет-маркетинга

Что нам сулит переход от HTTP/1.1 к HTTP/2

Posted on | November 30, 2015 | No Comments

Коротко расскажу о том, что делается для улучшения скорости загрузки веб-страниц, пользовательского опыта (user experience) на уровне протокола HTTP.
Спецификация Hypertext Transfer Protocol HTTP/1.1 RFC 2068 была впервые опубликована в Январе 1997 года, далее последовала июньская редакция 1999 года RFC-2616. После этого всемирная сеть внешне бурно развивалась, а ее скрытая от глаз основа, в видете коммуникационного протокола, оставалась неизменной вплоть до недавнего времени, а полный переход займет еще далеко не один год.
Долгое время HTTP/1.1 полностью устраивал большинство веб-разработчиков, однако по мере расширения интернет-каналов у конечных пользователей и (можно сказать, как следствие) перехода веб-приложений к Web 2.0 архитектуре, стали заметны недостатки протокола.
Что же пошло не так?

С какого-то момента всё возрастающая bandwidth (пропускная способность) канала перестала играть большую роль в скорости загрузки веб-страницы. Latency или round-trip delay time (RTD, RTT), иными словами — время требуемое на отправку запроса и получение ответа, стало очень важным фактором скорости загрузки веб-страницы в современном интернете.
Например, полная загрузка ленты новостей у Facebook требует примерно 8 секунд и не менее 250 HTTP запросов для получения различных ресурсов (изображений, CSS таблиц, JS скриптов и другие). Сами страницы, конечно, тоже сильно увеличились в размерах. Однако, в большей степени именно непомерно возросшее количество дополнительных ресурсов, нужных для отрисовки веб-страницы, после ее загрузки и стало самым узким местом для HTTP/1.1

f

Тайминг полной загрузки страницы ленты в Facebook (без времени загрузки зависимых ресурсов)


HTTP/1.1 работает поверх транспортного протокола TCP, поэтому наследует как его достоинства так и недостатки, добавляя к нему свои.
1. 3-way handshake
Из-за двухстороннего обмена пакетами для установки “надежного” TCP соединения требуется достаточно много времени

3-way TCP handshake schema

3-way TCP handshake. Wikimedia

И только после установки соединения може быть отправлен HTTP/1.1 запрос вида
GET /index.html HTTP/1.1
HOST: …
{%HEADERS%}

К слову сказать, RTT (round-trip time) из Европы в США может составлять около 200 ms (миллисекунд).

2. TCP slow start
Клиент и сервер не редко разделены тысячами километров, а это значит что между ними стоит множество рутеров, шлюзов, прокси, которые должны иметь достаточно ресурсов для обработки пакета данных большого размера. Если приходит пакет, на обработку которого у промежуточного устройства не хватает ресурсов, то он будет отклонен. А чтобы не тратить драгоценное время на предварительное выяснение каким объемом данных за единицу времени клиент и сервер могут обмениваться, существует стратегия медленного старта для контроля над нагрузкой сети. Суть которой сводится к тому, что пересылаемый объем пересылаемых данных пропорционально увеличивается до тех пор, пока получатель подтверждает его получение.
Ввиду этого новое соединение будет также иметь дополнительный overhead на “прогрев”.

3. В конце 90х уже было ясно 3-way handshake существенно увеличивает Latency, поэтому в HTTP/1.1 по умолчанию используются Keep-Alive соединения, предусматривающие переиспользование соединения для новых запросов на тот же домен. Для увеличения скорости загрузки страницы с нескольками сотнями ресурсов нужно много соединений, но каждое соединение обрабатываемое сервером – это дополнительная нагрузка на него и не все сайты могут выдержать большое количество одновременных соединений. Как следствие в современных браузерах стоит ограничение на кол-во одновременных соединений с клиента на домен.

4. HTTP Pipelining & Head of line blocking (HOL blocking)
Для ускорения загрузки сайтов с high latency соединениям в протокол HTTP/1.1 была разработана техника Pipelining, которая позволяла клиенту отправлять запросы на сервер пачками, однако возвращать ответы на них он должен как в FIFO (first in first out) очереди

HTTP 1.1 Pipelining schema

HTTP/1.1 Pipelining Wikipedia

Основные методы обхода этих ограничений:
1. Domain sharding
Если веб-сайт рассчитан под соответствующие нагрузки, то для обхода ограничения кол-ва соединений на домен используется разделение ресурсов по разным доменам.
Например, разные по типу ресурсы будут отдаваться с поддоменов img.yoursite.com, css.yoursite.com, js.yoursite.com, а XHR запросы будут идти на основной домен.
Таким образом к каждому из доменом может быть одновременно по X запросов, вместо ограничения X запросов на все типы ресурсов расположенных на одном домене.

2. Resource inlining, Data URI
Уменьшает количество запросов на сервер путем встраивания небольших ресурсов в страницу, это работает с css, js файлами и даже с картинками, например, вместо

<html>
  <head>
    <title>Image test example</title>
  </head>
  <body>
    <img src="images/Cuppa.png">
  </body>
</html>

будет отдан html

<html>
  <head>
    <title>Image test example</title>
  </head>
  <body>
    <img src="data:image/png;base64,...Base64 data">
  </body>
</html>

3. Сoncatenating files, spriting images
Объединять множество нужных CSS или JS файлов в один большой и объединять небольшие картинки в одну большего размера, с последующем CSS позиционированием отдельных кусков большого изображения в местах где ранее загружались небольшие изображения.
Каждый из описанных выше подходов имеют не только плюсы, но и минусы, которые я не буду рассматривать в рамках этой статьи.

Первые крупные шаги были сделаны компанией Google. В 2009 году они объявили о разработке протокола SPDY, целью которого было ускорить загрузку веб-страниц. Спустя год Google внедрил поддержку протокола во все версии браузера Chrome 6, после чего протокол начали поддерживать сначала ресурсы компании, а после другие сайты и веб-сервера. В конце 2012 SPDY стал основой для разрабатывающегося протокола HTTP/2.

Что же представляет из себя HTTP/2 (RFC 7540)
Во-первых HTTP/2 — это бинарный протокол, а не текстовый, так что уже не получится так просто подключиться через telnet к серверу и отсылать запросы, получать читаемые ответы. С другой стороны будет уменьшение кол-ва гоняемых при запросах/ответах данных и проще упростится их парсинг.
У новой версии не будет обратной совместимости с редакцией 1.1, потому что в ней протокол был текстовый. Семантически HTTP/2 не изменится в сравнении с HTTP/1.1 останутся те же GET POST и другие запросы.
Использование HTTP/2 возможно как поверх HTTP/1.1 через HTTP/2 Upgrade (h2c), так и через через TLS + ALPN (h2). Второй вариант использует защищенное соединение и уже поддерживается большинством современных браузеров.

Новая версия протокола в корне отличается от предыдущей своей архитектурой.
На один домен достаточно использовать одно персистентное соединение, которое теперь имеет много потоков (streams) состоящих из последовательности фреймов (frames), каждый из которых представляет отдельный запрос/ответ. Потоки позволяют одновременно (и в любой момент времени) запрашивать множество ресурсов и получать их в заданном порядке, не обязательно в FIFO как сделано в HTTP/1.1 Pipelining. Клиент может задать приоритет конкретного потока через HEADERS frame при открытии потока или через передачу PRIORITY frame в любой момент жизни потока. Цель этого параметра — выразить предпочтение при выделении ресурсов на обработку этого потока отвечающей стороной, при одновременной обрабатке нескольких потоков.
Например, можно задать следующие правила: отдавать изображения быстрее CSS файлов, а CSS файлы быстрее JS скриптов. При этом приоритет внутри типа ресурсов может быть задана алфавитным порядком.
Также потоки могут иметь зависимость от друг друга, таким образом можно задавать очередность обработки потоков.
Большое внимание было уделено оптимизации заголовков, для это был создан стандарт работы со сжатыми заголовками HPACK Header Compression for HTTP/2 (RFC 7541)
HPACK использует алгоритм Huffman Encoding для сжатия HEADER записей, таблица частот хранится в памяти на обеих конечных точках соединения.
Server Push
Теперь сервер имеет возможность отправить ответ без явного запроса с клиента, что может быть полезно в случаях когда сервер знает что клиенту понадобится этот ответ для полной обработки отправленного ранее запроса. Ответ сервера может быть закеширован. Клиент может отказаться принимать тело ответа (DATA frames) или заблокировать эту возможность. Server push может быть удобен в том случае, когда сервер еще отдает результаты на запрос страницы и, зная что в этой странице будут ссылки на не загруженные ранее изображения, начинает их отдавать на клиент до получения явного запроса с клиента (который произойдет после того, как он распарсит кусок запрашиваемого документа с линком на изображение).

В феврале 2015 года Google заявил об отказе поддержки SPDY протокола в 2016 года в виду скорой ратификации финальной версии HTTP/2 стандарта.
В сентябре 2015 года веб-сервер Nginx убрал поддержку SPDY в версиях 1.9.5+ в пользу HTTP/2.
Apache 2.4.12+, Apache Tomcat 9.x, Wildfly 9.x и Jetty 9.3+ тоже имеют поддержку обновленной версии протокола.
На стороне Java библиотек стандарт представлен в библиотеках Curl, Jetty, Netty, OkHttp.

Поддержка HTTP/2 в браузерах

Поддержка HTTP/2 в браузерах на конец 2015 г. Can I Use

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

SEO Community Ваау! News2.ru SMI2 Google Bookmarks I.ua Закладки Yandex Ruspace Web-zakladka Zakladok.net delicious БобрДобр.ru Memori.ru rucity.com МоёМесто.ru Mister Wong

Comments