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