Представлена альфа версия патча, обеспечивающего поддержку HTTP/2 для NGINX. Для данного патча необходим NGINX версии 1.9.0 или новее. Полная поддержка протокола HTTP/2 для коммерческой и некоммерческой версий NGINX планируется к концу этого года. Отзывы можно отправить в рассылку nginx-devel.

Так как патч является альфа версией, не рекомендуется его использовать в рабочих проектах. Если есть желание использовать особенности HTTP/2 для рабочих сайтов, следует обратить внимание на NGINX версии 1.5.10 и более новых, в которых реализована полная поддержка протокола SPDY/3.1. Как предшественник HTTP/2, SPDY обладает такими же приемуществами как и HTTP/2, но в то же время имеет более широкую поддержку среди актуальных версий браузеров.

О поддержке HTTP/2 в NGINX


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

Для облегчения перехода к новому протоколу NGINX действует как “HTTP/2 шлюз”. На стороне клиента NGINX общается с браузерами через HTTP/2 (если для браузера реализована поддержка HTTP/2), а на стороне сервера через HTTP/1.x (или FastCGI, uwsgi, SCGI) как раньше. В промежутке между клиентом и бекендом NGINX преобразует HTTP/2 в HTTP/1.x (или FastCGI, и т.д.). Иными словами, сервера и приложения, проксируемые через NGINX, не требуют изменений для перехода на HTTP/2. Единственным необходимым изменением существующих HTTPS конфигураций будет добавление параметра http2 к директивам listen (ssl параметр также необходим):

listen 443 ssl http2 default_server;

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

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

Сборка NGINX c HTTP/2


  1. Устанавливаем OpenSSL версии 1.0.2 или новее, необходимый для поддержки ALPN.
  2. Скачиваем и распаковываем NGINX версии 1.9.0 или новее:
    $ wget http://nginx.org/download/nginx-1.9.3.tar.gz
    $ tar zxvf nginx-1.9.3.tar.gz
    $ cd nginx-1.9.3

  3. Скачиваем патч:
    $ wget http://nginx.org/patches/http2/patch.http2.txt

  4. Проверяем возможность применения патча:
    $ patch -p1 --dry-run < patch.http2.txt

  5. Если ошибок нет – применяем:
    $ patch -p1 < patch.http2.txt

  6. Конфигурируем NGINX с необходимыми опциями:
    • для сборки NGINX вместе с OpenSSL из исходников и статической линковки:
      $ ./configure --with-http_ssl_module               --with-http_v2_module               --with-debug               --with-openssl=/path/to/openssl-1.0.2               ...
    • если OpenSSL установлен как сторонняя библиотека (например в Mac OS X):
      $ ./configure --with-http_ssl_module               --with-http_v2_module               --with-debug               --with-cc-opt="-I/opt/local/include"               --with-ld-opt="-L/opt/local/lib"               ...

  7. После этого собираем NGINX:
    $ make

Настройка NGINX


Для включения поддержки HTTP/2 добавьте параметры ssl и http2 к директивам listen:
server {
    listen 443 ssl http2 default_server;

    ssl_certificate     server.crt;
    ssl_certificate_key server.key;
    ...
}

Замечание: параметр ssl является обязательным. На момент написания статьи в браузерах не реализована поддержка HTTP/2 без SSL шифрования.

Для проверки работоспособности HTTP/2 есть неплохие плагины для Google Chrome и Firefox.

Замечания


Как это бывает с ранними релизами, есть некоторое количество проблем:

  • Патч находится в состоянии ранней альфы и может использоваться только для тестирования. В данное время над модулем ведется активная работа и мы будем благодарны всем, кто примет участие в тестировании (результаты можно прислать в nginx-devel).
  • 'Server Push' не реализован в этой версии патча и не будет поддержан в первой рабочей реализации HTTP/2. Возможно, данный функционал появиться в следующих версиях NGINX.
  • Патч удаляет модуль SPDY и заменяет его модулем HTTP/2. То есть после применения данного патча настроить NGINX с использованием SPDY не удастся. Это также будет сделано в первой рабочей версии HTTP/2 для коммерческой и некоммерческой версий. SPDY объявят устаревшим в начале 2016 г., поэтому нет необходимости поддерживать обе директивы.

Особые благодарности


NGINX, Inc. выражает благодарность компаниям Dropbox и Automattic, которые являются активными пользователями NGINX и участвуют в спонсировании разработки. Их вклад ускорил создание HTTP/2 модуля и мы надеемся, что у вас в свою очередь будет возможность поддержать их.

UPD: Поддержка HTTP2 уже добавлена в open-source версию NGINX. Все желающие могут скачать исходники.

Комментарии (24)


  1. BuriK666
    07.08.2015 17:41

    Радует что NGINX не поддерживает http2 без ssl, как и Google Chrome.


    1. VBart
      07.08.2015 17:53
      +1

      Поддерживает. Это полезно для тестов и когда распаковка TLS осуществляется где-то раньше.


    1. dreik
      07.08.2015 17:54
      +5

      процитирую VBart из листа nginx-ru:

      Она есть, мы её для собственных функциональных тестов используем.

      В браузерах поддержки нет и, насколько мне известно, пока не планируется.
      Тому есть как минимум две причины:

      1. Может не работать если пользователь за прокси;

      2. Смысла немного, HTTP/2 — это экономия на хэндшейках, которые для TCP
      не такие дорогие, как для TCP+TLS.


  1. Gendalph
    07.08.2015 19:16

    Очень прошу добавить примечание по make install — вместо него необходимо использовать checkinstall, что позволит потом безболезненно удалить пакет.

    PS: когда за make install начнут ломать руки?


    1. VBart
      07.08.2015 19:49
      +6

      Мир гораздо шире и не ограничивается системами где есть checkinstall. Вообще для потестировать не нужно ставить nginx в систему. Тут правильнее будет убрать из статьи make install (собственно у меня в README её и нет: nginx.org/patches/http2/README.txt).


      1. Gendalph
        07.08.2015 20:00
        +1

        Я знаю, но заметку нужно делать — очень многие по-прежнему кроме make && make install ничего не знают.


        1. VBart
          07.08.2015 20:06

          Я согласен.


    1. k0ldbl00d
      07.08.2015 20:58
      +2

      Руки начнут ломать, когда не останется дистрибутивов, кроме ответвлений от Debian.


      1. Gendalph
        07.08.2015 21:22

        checkinstall -R?
        makepkg?
        ebuild?
        На *BSD, конечно, ничего иного кроме make install не остается, но там люди сами знают что делать.


        1. k0ldbl00d
          07.08.2015 22:25
          +3

          Ну вот и надо было об этом раньше писать, а то только checkinstall.


          1. Gendalph
            07.08.2015 22:36

            Речь о безоговорочном make install.
            checkinstall покрывает все .deb (checkinstall -D) и .rpm (checkinstall -R) дистрибутивы — Debian, Ubuntu, RHEL, CentOS, SUSE — основная масса инсталляций.
            makepkg — ArchLinux и основанные на нём — там люди сами знают что к чему.
            ebuild — Gentoo, no comment.
            make install — для тех дистрибутивов и систем, где build-система не предусматривает удобного сбора пакетов (какой-нибудь LFS, *BSD, прочие), но в этом случае пользователь сам знает что и куда.


            1. Zelgadis
              08.08.2015 00:24
              +4

              Вот не надо. pkg-ng во FreeBSD удобная штука. Порты конечно уже удобнее. Добавить этот модуль в портовый nginx если этого еще не сделали не так уж и сложно.


              1. Gendalph
                08.08.2015 00:31

                Признаю, я тут отстал, но это отличные новости.


    1. KAndy
      07.08.2015 21:42
      +2

      а какие проблемы make install сделанного в docker контейнере?


      1. Gendalph
        07.08.2015 21:47
        -2

        Я, честно говоря, пока не добрался до Docker'а, но мне кажется что это не совсем правильно — собирать в контейнере приложение, правильнее будет ставить пакет (возможно предварительно собранный в другом контейнере).


      1. cy-ernado
        08.08.2015 00:16
        +1

        Никаких.


        1. cy-ernado
          08.08.2015 21:08

          Если кому нужно, обновил свой Dockerfile для nginx с pagespeed, заменив spdy на http2.
          Openssl не очень очевидно для меня ставится :)

          github.com/cydev/nginx/blob/master/Dockerfile


      1. Zelgadis
        08.08.2015 00:37
        +3

        Хмм, как насчет того, что это требует всей обвязки для make install внутри контейнера? Какое-то не логичное использование контейнеров.


    1. edwardspec
      08.08.2015 04:09
      +7

      > что позволит потом безболезненно удалить пакет.
      > PS: когда за make install начнут ломать руки?

      Не ранее чем отовсюду исчезнет configure.
      Которому можно сказать --prefix=/opt/nginx и делать make install спокойно.


    1. vagran
      08.08.2015 08:08
      +8

      Что за бред. А если я свой префикс указал для configure? В чём проблема мне его потом удалить? Руки ломать надо за навязывание абсолютных утверждений и субъективного мнения.


    1. Fr0stb1te
      08.08.2015 14:34
      +3

      Когда за повторение за другими категоричных утверждений начнут ломать руки?

      1) Это моя машина, что хочу, то и делаю.
      2) /usr/local


  1. Anakros
    15.08.2015 18:25

    Пользователям homebrew: gist.github.com/Anakros/1891d0b4ec3ca2e34d97


  1. DIvan4ik
    31.08.2015 16:44

    У кого нибудь проходит проверка на http/2?


  1. deep_orange
    11.09.2015 02:17

    А что же делать если мне не составляет проблем поднять два аналогичных сервера за Nginx — для http и для http2. Но как делить по протоколу мне не ясно. А так получается, я выпилю оптимизацию для стариков и они начнут тормозить ещё сильней. А ведь это не только нагрузка на клиента. Если вместо одного спрайта я буду пихать 50 картинок подряд. У меня каналов не хватит хватит конечно, я же чисто протестировать. Но сама такая возможность интересует. Я не совсем уверен, что я смогу пулять статику как-то иначе, не прибегая к двум серверам одновременно, так, чтобы оптимизация для стариков работала и для HTTP/2, кто поддерживает. SSL в обязаловку.