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

时间:2017-01-13 14:40:18

标签: node.js nginx http2

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

我最近设置了nginx以使用HTTP2和SSL(h2)。似乎HTTP2确实启用并正常工作。

但是,我想知道代理连接(nginx< - > node.js)使用HTTP 1.1的事实是否会影响性能。也就是说,我在速度方面缺少HTTP2优势,因为我的内部连接是HTTP 1.1?

5 个答案:

答案 0 :(得分:40)

一般来说,HTTP / 2的最大直接好处是multiplexing为浏览器连接提供的速度提升,这通常会受到低延迟的阻碍。这些也减少了多个连接的需求(和费用),这是尝试在HTTP / 1.1中实现类似性能优势的一种解决方法。

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

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

然而,一直支持HTTP / 2有潜在的好处。例如,它可以允许服务器从应用程序一直推送。由于HTTP / 2的二进制特性和报头压缩,最后一跳的数据包大小减少也带来了潜在的好处。虽然像延迟一样,带宽通常不是内部连接的问题,因此这一点的重要性是有争议的。最后一些人争辩说,反向代理连接HTTP / 2连接到HTTP / 2连接的工作少于对HTTP / 1.1连接的工作,因为不需要将一个协议转换为另一个协议,尽管我对此持怀疑态度。这甚至是显而易见的,因为它们是单独的连接(除非它仅仅作为TCP通过代理)。所以,对我来说,端到端HTTP / 2的主要原因是允许端到端服务器推送,但是even that is probably better handled with HTTP Link Headers and 103-Early Hints due to the complications in managing push across multiple connections

目前,虽然服务器仍在增加支持并且服务器推送使用率很低(并且仍在进行实验以定义最佳实践),但我建议仅在终点处使用HTTP / 2。在编写本文时,Nginx还没有为ProxyPass连接支持HTTP / 2(尽管Apache确实如此),并且no plans to add this,并且他们对单个HTTP / 2连接是否可能提出了一个有趣的观点引入缓慢(强调我的):

  

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

     

简短回答:

     

不,没有计划。

     

答案很长:

     

实现它几乎没有意义,因为主要的HTTP / 2好处   是它允许在一个单独的多路复用许多请求   连接,因此[几乎]删除了数量的限制   simalteneous requests - 并且在与之交谈时没有这样的限制   你自己的后端。 此外,使用时情况可能会变得更糟   HTTP / 2到后端,因为使用了单个T​​CP连接   多个

     

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

     

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

最后,还应该注意的是,虽然浏览器需要HTTPS for HTTP / 2(h2),但大多数服务器都没有,因此可以通过HTTP(h2c)支持最后一跳。因此,如果节点部分不存在端口加密,则不需要端到端加密(因为它通常不是)。但是,根据后端服务器相对于前端服务器的位置,如果流量将通过不安全的网络(例如,通过互联网将CDN传送到源服务器),则甚至可以考虑使用HTTPS进行此连接。 / p>

答案 1 :(得分:6)

NGINX不支持HTTP / 2作为客户端。由于他们在同一台服务器上运行并且没有延迟或有限的带宽,我不认为它会产生很大的不同。我会确保你在nginx和node.js之间使用keepalive。

https://www.nginx.com/blog/tuning-nginx/#keepalive

答案 2 :(得分:5)

NGINX现在支持HTTP2 / Push,太棒了...

在这里,我也从我的静态子域中推送了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;
        }

答案 3 :(得分:3)

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

答案 4 :(得分:2)

如果在不方便使您的服务与HTTP2兼容的情况下有人正在寻找解决方案。这是NGINX的基本配置,可用于将HTTP1服务转换为HTTP2服务。

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;
  }
}