Глава 8. HTTP/2

Введение

HTTP/2 основной ревизией протокола HTTP. Большая часть выполненной в этой версии работы сосредоточена на его транспортном уровне, например, разрешение мультиплексирования полного запроса и отклика поверх отдельного подключения TCP. За счёт применения сжатия полей заголовка HTTP были достигнуты высокие показатели эффективности, к тому же была добавлена поддержка приоритетов для запросов. Другим крупным добавлением в этот протокол стала возможность для конкретного сервера активно доставлять сообщения своему клиенту. Данная глава описывает подробности базовой конфигурации для включения в NGINX HTTP/2, а также настройку поддержки gRPC и активной доставки сервера HTTP/2.

Базовая настройка

Задача

Вы желаете воспользоваться преимуществами HTTP/2.

Решение

Включите HTTP/2 в своём сервере NGINX:


server {
    listen 443 ssl http2 default_server;

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

Обсуждение

Для включения HTTP/2 вам просто требуется добавить соответствующий параметр http2 к своей директиве listen. Однако засада в том, что хотя сам протокол и не требует обёртки своего подключения в SSL/ TLS, некоторые реализации клиентов HTTP/2 поддерживают исключительно HTTP/2 поверх шифрованных подключений. Следующее предостережение состоит в том, что в самой спецификации HTTP/2 несколько комплектов шифров TLS 1.2 занесено в чёрный список и следовательно будут отказывать при квитировании (handshake). Применяемые в NGINX по умолчанию шифры не находятся в этом чёрном списке. Для проверки того что ваша установка правильная вы можете установить некий подключаемый модуль для браузеров Chrome и Firefox, который указывает когда некий сайт применяет HTTP/2 или из командной строки при помощи утилиты nghttp.

Также ознакомьтесь

HTTP/2 RFC Blacklisted Ciphers

Chrome HTTP2 and SPDY Indicator Plugin

Firefox HTTP2 Indicator Add-on

gRPC

Задача

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

Решение

Для посредничества (прокси) подключений gRPC воспользуйтесь NGINX.


server {
    listen 80 http2;

    location / {
        grpc_pass grpc://backend.local:50051;
    }
}
 	   

В этой конфигурации NGINX выполняет ожидание по порту 80 для обмена HTTP/2 без шифрования, а также выступает посредником для машины с названием backend.local по порту 50051. Установленная директива grpc_pass указывает NGINX на необходимость рассматривать такое подключение как некий вызов gRPC. Указание grpc:// в самом начале местоположения нашего сервера backend не требуется; тем не менее, это непосредственно указывfет на то, что данное подключение backend не шифруется.

Чтобы воспользоваться шифрованием TLS между данными клиентом и NGINX и прерывать такое шифрование перед необходимыми вызовами имеющегося сервера приложений включите SSL и HTTP/2 как вы это делали в нашем первом разделе:


server {
    listen 443 ssl http2 default_server;

    ssl_certificate server.crt;
    ssl_certificate_key server.key;
    location / {
        grpc_pass grpc://backend.local:50051;
    }
}
 	   

Данная конфигурация прекращает TLS в NGINX и передаёт соответствующее взаимодействие gPRC в имеющееся приложение поверх не зашифрованного HTTP/2.

Для настройки NGINX на шифрование всего взаимодействия gRPC со своим сервером приложения предоставьте повсеместное шифрование обмена, просто изменив имеющуюся директиву grpc_pass, определив grpcs:// перед уже имеющейся информацией о сервере (обратите внимание на добавление символа s, обозначающего безопасное взаимодействие):


grpc_pass grpcs://backend.local:50051;
 	   

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


location /mypackage.service1 {
    grpc_pass grpc://backend.local:50051;
}
    location /mypackage.service2 {
    grpc_pass grpc://backend.local:50052;
}
location / {
    root /usr/share/nginx/html;
    index index.html index.htm;
}
 	   

Данный пример конфигурации применяет директиву location для направления входящего обмена HTTP/2 между двумя обособленными службами gRPC, а также некое location для обслуживания статического содержимого. Вызовы метода для установленной службы mypackage.service1 направляются в сервер backend.local по порту 50051, а вызовы для mypackage.service2 отправляются в порт 50052. Установленное location / перехватывает все прочие запросы HTTP и обслуживает статическое содержимое. Это демонстрирует как NGINX способен обслуживать gRPC и не- gRPC под одной и той же оконечной точкой HTTP/2 и выполнять надлежащим образом маршрутизацию.

Вызовы балансировки нагрузки также похожи на обмен HTTP без gRPC:


upstream grpcservers {
    server backend1.local:50051;
    server backend2.local:50051;
}
server {
    listen 443 ssl http2 default_server;

    ssl_certificate server.crt;
    ssl_certificate_key server.key;
    location / {
        grpc_pass grpc://grpcservers;
    }
}
 	   

Приведённый блок upstream работает в точности так же для gRPC, как он делал это для обмена HTTP. Единственное отличите состоит в том, что этот upstream получает ссылку через grpc_pass.

Обсуждение

NGINX обладает возможностью получать, выступать посредником, выполнять балансировку нагрузки, осуществлять маршрутизацию и прекращать шифрование для вызовов gRPC. Имеющийся модуль gRPC позволяет NGINX устанавливать, изменять или сбрасывать заголовки вызова gRPC, выставлять таймауты для запросов и устанавливать спецификации восходящего SSL/ TLS. Так как gRPC выполняет взаимодействие поверх протокола HTTP/2, вы можете настроить NGINX на приём gRPC и не gRPC веб- обмена в одной и той же оконечной точке.

Сервер активной доставки HTTP/2

Задача

Вам требуется активно доставлять своему клиенту содержимое упреждающим образом.

Решение

Воспользуйтесь функциональностью NGINX активной доставки HTTP/2.


server {
    listen 443 ssl http2 default_server;

    ssl_certificate server.crt;
    ssl_certificate_key server.key;
    root /usr/share/nginx/html;

    location = /demo.html {
        http2_push /style.css;
        http2_push /image1.jpg;
    }
}
 	   

Обсуждение

Для применения активной доставки сервера HTTP/2 ваш сервер обязан быть настроенным для HTTP/2, как это было нами сделано в рецепте Базовая настройка. Здесь вы можете указать NGINX на необходимость упреждающей активной доставки определённых файлов при помощи директивы http2_push. Эта директива получает один параметр, значение полного пути URI того файла, который активно доставляется вашему клиенту.

NGINX таке способен автоматически активно доставлять клиентам ресурсы если выступает посредником (прокси) в приложениях, содержащих некий заголовок отклика HTTP с названием Link. Такой заголовок имеет возможность указывать NGINX на упреждающую загрузку предписанных ресурсов. Чтобы включить данную функциональность добавьте в настройки своего NGINX http2_push_preload on;.