Nodejs http2 позади (nginx или другой веб-сервер) с Push в Nodejs
Я пытаюсь обновить наш Onlineshop до http2 с возможностями Server Push, но я не могу найти решение для веб-сервера, такого как nginx(для прокси и некоторых других вещей) с Upstream http2. Мы используем nodejs с модулем http узла в данный момент, но переключимся на модуль узла spdy. Модуль Spdy поддерживает http2 с Server Push. Я пробовал использовать h2o как альтернативу nginx, но он также не поддерживает http2 Upstream.
Я заблудился в данный момент и нуждаюсь в помощи
2 ответа
Nginx только что добавил поддержку HTTP/2 Push, поэтому, если вы не теряете последнюю основную версию, вы не сможете этого сделать. Кроме того, потому что это так ново , все еще есть некоторые проблемы с этим. Nginx не поддерживает http2 через внутренние соединения (и заявляет, что не будет поддерживать это). Таким образом, вы не можете напрямую вытолкнуть систему вниз по течению, как вы предлагаете.
Есть некоторый вопрос относительно того, является ли это лучшим способом подтолкнуть в любом случае. Нисходящая система может передавать на вышестоящий прокси-сервер, даже если клиент не поддерживает, например, push - что является потраченным впустую.
Таким образом, лучший способ состоит в том, чтобы выдвинуть прокси-сервер и попросить нижестоящую систему сообщить вышестоящей системе (через заголовки канала) о том, что нужно сделать это. Это имеет несколько преимуществ в уменьшении сложности, позволяя последующей системе передавать ресурсы, которые она может не контролировать (например, статические ресурсы, такие как таблицы стилей, JavaScript, изображения и т. Д.), Центральное хранилище уже загруженных ресурсов (дайджесты кэша), а также не требует, чтобы HTTP / 2 поддерживался полностью (заголовки ссылок могут быть отправлены через HTTP/1.1 так же легко, как HTTP/2).
Основным недостатком проталкивания от прокси восходящего потока через заголовки ссылок является то, что вы должны ждать готовности запрошенного ресурса, так как заголовки ссылок читаются из ответа. Если для создания ресурса запроса требуется некоторое время, то может быть выгоднее начать проталкивать другие ресурсы во время его обработки. Эта проблема решается с помощью нового кода HTTP 103 "Ранние подсказки", в котором вы можете ответить раньше, прежде чем отправлять основной код состояния 200 позже. Это раннее сообщение может иметь заголовки ссылок, которые могут быть прочитаны вышестоящим прокси и использоваться для отправки ресурса. Я не уверен, что реализация Nginx это поддержит.
Между прочим, Apache уже некоторое время поддерживает Push и имеет гораздо более зрелую реализацию. Он поддерживает его через прямую конфигурацию Apache или через заголовки ссылок (в том числе через 103 ответа, которые по умолчанию настроены так, чтобы их нельзя было отправлять в случае проблем совместимости). Он даже поддерживает проксирование к бэкэндам через HTTP / 2, но не поддерживает прямую передачу через серверные соединения по причинам, описанным выше. Некоторые другие менее известные серверы (например, H2O) также поддерживают HTTP / 2 лучше, чем Nginx.
Наконец, если используется CDN, они могут поддерживать HTTP/2 Push (часто через заголовки ссылок) без необходимости обновления какой-либо серверной инфраструктуры. На самом деле Cloudflare - это CDN на основе Nginx, который какое-то время имел HTTP/2 Push, и я считаю, что это два инженера Cloudflare, которые перенесли свою реализацию в базовый код Nginx.
После NGINX 1.13.9 (только что перенесенного на основную линию сегодня) вы можете получить HTTP/2-сервер из коробки, скомпилировав его с ngx_http_v2_module
,
Если вас интересует недавнее добавление, это коммит, который добавил большую часть функциональности: hg.nginx.org: HTTP/2: push server.
Его использование относительно просто: добавьте http2_push_preload
Директива к серверу, который проксирует узел, а затем от узла использовать Link
заголовок (как описано в спецификации W3 - https://www.w3.org/TR/preload/), а затем NGINX выполнит работу по отправке кадра h2, который указывает на толчок сервера.
Например, предположим, что у вас есть /
конечная точка, которая обслуживает регулярный index.html
но и толкает image.svg
клиенту.
В NGINX вы можете настроить вышестоящий сервер, а затем включить конфигурацию сервера. http2_push_preload
на конфигурации сервера:
# Add an upstream server to proxy requests to.
upstream sample-http1 {
server localhost:8080;
}
server {
# Listen on port 8443 with http2 support on.
listen 8443 http2;
# Enable TLS such that we can have proper HTTP2
# support using browsers.
ssl on;
ssl_certificate certs/cert_example.com.pem;
ssl_certificate_key certs/key_example.com.pem;
# Enable support for using `Link` headers to indicate
# origin server push.
http2_push_preload on;
# Act as a reverse proxy for requests going to /proxy/*.
#
# Because we don't want to rewrite our endpoints in the
# Node app, rewrite the path such that `/proxy/lol` ends up
# as `/lol`.
location / {
proxy_pass http://sample-http1;
}
}
Тогда в приложении NodeJS вы бы служили /
как обычно, но добавьте дополнительный Link
заголовок к ответу:
response.setHeader('Link', '</image.svg>; rel=preload; as=image');
пс.: да, вы бы оставили эти угловые скобки; Я не имею в виду, что вы должны заменить их.
Кстати, пример, который я только что дал (с некоторыми советами по отладке), полностью описан здесь: https://ops.tips/blog/nginx-http2-server-push/.
Вы можете скомпилировать / перекомпилировать nginx из исходного кода и включить --with-http_v2_module
параметр конфигурации, чтобы включить возможности HTTP2 push.