Новый Nginx с HTTP/2 и JavaScript

Уже доступен новый выпуск основной ветки сервера nginx 1.9.5. Ключевым новшеством является интеграция модуля ngx_http_v2_module с поддержкой протокола HTTP/2 и встроенного парсера диалекта JavaScript – nginScript.

Веб давно живет на текстовом протоколе HTTP/1.1, который не менялся уже последние 16 лет. Текущая версия протокола HTTP/1.1 была стандартизирована RFC 2068 в 1997, а принята в 1999 году. Новшеством в этой версии было добавление режима «постоянного соединения»: TCP-соединение может оставаться открытым после отправки ответа на запрос, что позволяет посылать несколько запросов за одно соединение. Клиент обязан посылать информацию об имени хоста, к которому он обращается, что сделало возможной более простую организацию виртуального хостинга.

Web стремительно развивается, бизнес- логика постепенно перешла с серверов на клиенты (браузеры). Количество объемов загружаемой информации на одну веб-страницу значительно выросло, а с ростом популяризации мобильного интернета снова стал актуальным вопрос быстрой загрузки на узких каналах. Наступила необходимость в усовершенствовании протертого до дыр протокола HTTP/1.1.

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

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

HTTP/2.0

11 февраля 2015 года были опубликованы финальные версии черновика новой версии HTTP протокола. Протокол, хоть и носит название «Hyper Text Transfer Protocol», тем не менее, является бинарным, в отличие от предыдущих версий. Протокол HTTP/2 основан на базе протокола SPDY и был разработан рабочей группой Hypertext Transfer Protocol working group (httpbis, где bis означает «еще раз», «повторно», «на бис») из Internet Engineering Task Force.

SPDY – протокол прикладного уровня для передачи веб-контента, разработан корпорацией Google. Позиционировался как замена некоторых частей HTTP – таких, как управление соединениями и форматы передачи данных. На сегодня его разработка прекращена, а в сервере Nginx 1.9.5 поддержка SPDY полностью убрана. Этот нюанс стоит учитывать при переходе на новый сервер. В файлах конфигурации вместо «spdy» теперь нужно писать «http2».

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

Сравнение работы протоколов

Рабочая группа представила протокол HTTP/2 на рассмотрение IESG как Proposed Standard в декабре 2014 и IESG утвердила его к публикации 17 февраля 2015 года. Спецификация была опубликована как RFC 7540 в мае 2015 года. Протокол HTTP/2 поддерживается последними версиями браузеров Chrome, Opera, Firefox, Safari, Internet Explorer 11 и Microsoft Edge. На мобильных устройствах новый протокол поддерживается браузерами iOS Safari и Chrome for Android. По данным консорциума W3Techs, на август 2015 года доля всех веб-сайтов, поддерживающих протокол HTTP/2, составляет 1,2%.

Ключевые особенности нового протокола HTTP 2.0:

  • мультиплексирование запросов
  • расстановка приоритетов для запросов
  • сжатие заголовков
  • загрузка нескольких элементов параллельно, посредством одного TCP-соединения
  • поддержка проактивных push-уведомлений со стороны сервера

Переход на новый протокол HTTP 2.0

Одним из основных опасений является то, что для внедрения поддержки HTTP/2 требуется изменение архитектуры серверного приложения. На самом деле это не так. Для перехода на новый протокол не требуется сложных манипуляций, кроме пересборки и установки новой версии сервера. Так-же придется сделать небольшое изменение в существующих конфигурационных файлах – добавить к существующему HTTPS соединению параметр http2 к директиве listen:

listen localhost:443 ssl http2;

Сам Nginx действует как «HTTP 2.0-шлюз». На стороне клиента сервер общается с браузерами через протокол HTTP 2.0 при условии, что для браузера реализована поддержка HTTP/2 иначе будет работать SSL. На стороне сервера общение происходит через протокол HTTP/1.x или FastCGI, uwsgi, SCGI, в зависимости от вашего серверного стека, как и раньше. Таким образом, сервер и приложения, проксируемые через Nginx, не требуют изменений для перехода на новый протокол.

Для одновременной работы HTTP/1.x и HTTP/2 в Nginx используется Application Layer Protocol Negotiation (ALPN), являющийся расширением TLS. При подключении браузера к серверу посылается список поддерживаемых протоколов. Если в списке есть h2, то Nginx использует HTTP 2.0 для соединения. Если в браузере не реализована поддержка ALPN или в списке поддерживаемых протоколов нет h2, то Nginx будет использовать HTTP 1.x.

Старое хорошее – теперь новое плохое

С переходом на новый протокол часть оптимизаций, присущих для HTTP/1.1, теперь являются антипаттернами для HTTP 2. Среди таких оптимизаций:

  • использование спрайтов, объединение или инлайнинг картинок;
  • разделение ресурсов между доменами.

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