nginx代理后面带有node.js的HTTP2

nginx代理后面带有node.js的HTTP2,node.js,nginx,http2,Node.js,Nginx,Http2,我有一个node.js服务器运行在nginx代理后面。node.js正在端口3000上运行HTTP 1.1(无SSL)服务器。两者都在同一台服务器上运行 我最近将nginx设置为使用HTTP2和SSL(h2)。看来HTTP2确实已经启用并开始工作了 但是,我想知道代理连接(nginx node.js)使用HTTP 1.1是否会影响性能。也就是说,由于我的内部连接是HTTP 1.1,我是否错过了HTTP 2在速度方面的优势?NGINX不支持HTTP/2作为客户端。由于它们运行在同一台服务器上,没有

我有一个node.js服务器运行在nginx代理后面。node.js正在端口3000上运行HTTP 1.1(无SSL)服务器。两者都在同一台服务器上运行

我最近将nginx设置为使用HTTP2和SSL(h2)。看来HTTP2确实已经启用并开始工作了


但是,我想知道代理连接(nginx node.js)使用HTTP 1.1是否会影响性能。也就是说,由于我的内部连接是HTTP 1.1,我是否错过了HTTP 2在速度方面的优势?

NGINX不支持HTTP/2作为客户端。由于它们运行在同一台服务器上,没有延迟或有限的带宽,我认为这两种方式都不会有很大的不同。我会确保您在nginx和node.js之间使用keepalives


一般来说,您不会失去性能,因为nginx通过向节点后端创建多个同时请求来匹配浏览器通过HTTP/2进行的请求复用。(HTTP/2的主要性能改进之一是允许浏览器在同一个连接上同时执行多个请求,而在HTTP 1.1中,每个连接只能同时执行一个请求。而且浏览器也限制了连接的数量。)

一般来说,HTTP/2的最大直接好处是为浏览器连接提供了速度提升,而浏览器连接通常会受到高延迟(即缓慢的往返速度)的阻碍。这些还减少了对多个连接的需求(和费用),这是在HTTP/1.1中实现类似性能优势的一种变通方法

对于内部连接(例如,充当反向代理的Web服务器和后端应用服务器之间),延迟通常非常非常低,因此HTTP/2的速度优势可以忽略不计。此外,每个应用服务器通常已经是一个单独的连接,因此这里也没有收益

因此,只要在边缘支持HTTP/2,您就可以获得大部分性能优势。这是一种相当常见的设置-类似于HTTPS通常在反向代理/负载平衡器上终止的方式,而不是一直终止

但是,始终支持HTTP/2有潜在的好处。例如,它可以允许服务器从应用程序一路推送。由于HTTP/2和报头压缩的二进制特性,最后一跳的数据包大小减小也有潜在的好处。不过,和延迟一样,带宽对于内部连接来说通常不是什么问题,所以这一点的重要性是有争议的。最后,有人认为反向代理连接HTTP/2连接到HTTP/2连接比连接到HTTP/1.1连接所做的工作要少,因为不需要将一个协议转换为另一个协议,尽管我怀疑这是否值得注意,因为它们是独立的连接(除非它只是作为TCP传递代理)。因此,对我来说,端到端HTTP/2的主要原因是允许端到端服务器推送,但是

目前,虽然服务器仍在增加支持,而且服务器推送使用率很低(并且仍在试验以定义最佳实践),但我建议只在端点使用HTTP/2。在撰写本文时,Nginx也不支持ProxyPass连接的HTTP/2(尽管Apache支持),并且已经提供了,并且他们提出了一个有趣的观点,即单个HTTP/2连接是否会引入缓慢性(我的重点是):

是否计划在不久的将来支持HTTP/2代理

简短答复:

没有,没有计划

长答覆:

作为HTTP/2的主要优点,实现它几乎没有意义 它允许在一个单独的内存中多路复用多个请求 连接,从而[几乎]消除了对 简单的请求——与他人交谈时没有这样的限制 你自己的后端此外,使用时情况可能会变得更糟 HTTP/2到后端,因为使用了单个TCP连接 有多个

另一方面,实现HTTP/2协议和请求 上行模块中单个连接内的多路复用将 需要对上游模块进行重大更改

由于上述原因,没有计划在中实现HTTP/2支持 上游模块,至少在可预见的未来。如果你 仍然认为通过HTTP/2与后端对话是必要的- 请随意提供补丁


最后,还应该注意的是,虽然浏览器需要HTTP/2(h2)的HTTPS,但大多数服务器不需要,因此可以支持HTTP上的最后一跳(h2c)。因此,如果节点部分不存在端到端加密(通常不存在),则无需进行端到端加密。尽管如此,根据后端服务器相对于前端服务器所处的位置,如果流量将通过不安全的网络(例如,通过internet从CDN到源服务器)传输,则可能需要考虑使用HTTPS(即使是用于此连接).

NGINX现在支持HTTP2/Push for
proxy\u-pass
,而且非常棒

在这里,我正在从我的静态子域中推favicon.ico、minified.css、minified.js、register.svg、purchase_litecoin.svg。我花了一些时间才意识到我可以从子域中推送

location / {
            http2_push_preload              on;
            add_header                      Link "<//static.yourdomain.io/css/minified.css>; as=style; rel=preload";
            add_header                      Link "<//static.yourdomain.io/js/minified.js>; as=script; rel=preload";
            add_header                      Link "<//static.yourdomain.io/favicon.ico>; as=image; rel=preload";
            add_header                      Link "<//static.yourdomain.io/images/register.svg>; as=image; rel=preload";
            add_header                      Link "<//static.yourdomain.io/images/purchase_litecoin.svg>; as=image; rel=preload";
            proxy_hide_header               X-Frame-Options;
            proxy_http_version              1.1;
            proxy_redirect                  off;
            proxy_set_header                Upgrade $http_upgrade;
            proxy_set_header                Connection "upgrade";
            proxy_set_header                X-Real-IP $remote_addr;
            proxy_set_header                Host $http_host;
            proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header                X-Forwarded-Proto $scheme;
            proxy_pass                      http://app_service;
        }
位置/{
http2_推压_预加载打开;
添加标题链接“as=style;rel=preload”;
添加标题链接“as=script;rel=preload”;
添加标题链接“as=image;rel=preload”;
添加标题链接“as=image;rel=preload”;
添加标题链接“as=image;rel=preload”;
代理\隐藏\标题X帧选项;
proxy_http_版本1.1;
代理_重定向关闭;
代理设置头升级$http\U升级;
server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  server_name localhost;
  ssl on;
  ssl_certificate /Users/xxx/ssl/myssl.crt;
  ssl_certificate_key /Users/xxx/ssl/myssl.key;

  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
  }
}