使用Push in Nodejs

时间:2016-06-17 06:41:55

标签: node.js nginx webserver http2 h2o-http

我正在尝试更新我们的在线商店以使用具有服务器推送功能的HTTP / 2,但我找不到像Nginx这样的网络服务器(用于代理和其他一些东西)与上游HTTP / 2的解决方案。我们目前正在将Node.js与节点HTTP模块一起使用,但是想切换到节点spdy模块。 spdy模块支持带服务器推送的HTTP / 2。我已经尝试过H2O作为Nginx的替代品,但它也不支持HTTP / 2上游。

我现在有点失落,需要帮助。

3 个答案:

答案 0 :(得分:2)

Nginx有only just added support for HTTP/2 Push所以除非你在摩擦最新的主线版本,否则你将无法做到这一点。还因为它是如此新的there are still some issues with it。 Nginx不支持后端连接上的http2(并且有stated they won’t support this)。所以你不能像你建议的那样直接从下游系统推送。

对于这是否是最佳推送方式存在一些疑问。即使客户端不支持推送,下游系统也可能会推送到上游代理服务器 - 这是浪费的推送。

所以更好的方法是从代理推送并让下游系统告诉上游系统(通过链接头)进行推送。这在降低复杂性方面有几个优点,允许下游系统推送它可能无法控制的资产(例如静态资产,如样式表,JavaScript,图像......等),已推送资产的中央存储(缓存摘要),也不要求HTTP / 2一直受到支持(链接头可以像HTTP / 2一样通过HTTP / 1.1发送)。

通过链接头从上游代理推送的主要缺点是,您必须等待所请求的资源准备就绪,因为从响应中读取了链接头。如果请求资源需要一些时间来生成,那么在处理其他资源时开始推送可能更有利。这是通过新的103 Early Hints HTTP Status code解决的,您可以在稍后发送主200状态代码之前回复。此早期消息可以具有链接头,其可以由上游代理读取并用于推送资源。我不确定Nginx的实现是否会支持这一点。

顺便说一下,Apache已经支持Push一段时间了,而且实现起来要成熟得多。它通过直接Apache配置或链接头支持它(包括通过103响应,默认情况下配置为在兼容性问题时不发送)。它甚至支持通过HTTP / 2代理到后端does not support direct push over back end connections,原因如上所述。其他一些不太知名的服务器(例如H2O)也比Nginx更好地支持HTTP / 2。

最后,如果使用CDN,那么他们可能支持HTTP / 2推送(通常通过链接头),而无需升级任何后端基础设施。事实上,Cloudflare是一个基于Nginx的CDN,其had HTTP/2 Push for a while,我实际上是two Cloudflare engineers which have back ported their implementation to the base Nginx code

答案 1 :(得分:1)

在NGINX 1.13.9(今天刚推到主线)之后,您可以通过使用ngx_http_v2_module编译来启用HTTP / 2服务器。

如果您对最近添加的内容感兴趣,那么这是添加了大部分功能的提交:hg.nginx.org: HTTP/2: server push

它的使用相对简单:将http2_push_preload指令添加到代理Node的服务器,然后从节点使用Link标头(如W3规范中所述 - {{3} })然后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');

ps。:是的,你要保留那些尖括号;我并不是说你应该更换它们。

顺便说一下,我刚刚给出的示例(带有一些调试技巧)在这里写完:https://www.w3.org/TR/preload/#server-push-http-2

答案 2 :(得分:0)

您可以从源代码编译/重新编译nginx,并包含--with-http_v2_module配置参数以启用HTTP2推送功能。