使用 Java / Node.js / Go 等语言开发的 Web 服务通常会使用 Nginx 作为反向代理服务来实现负载均衡等功能,此时的 Web 服务相对于 Nginx 来说就是上游服务(upstream)。
一般在优化 Web 服务的性能时都会聚焦在 Web 服务本身,而容易忽视 Nginx 和上游服务之间的连接。Nginx 有很多带 proxy 前缀的指令,通常在配置反向代理时往往以为配置一个 proxy_pass
就完事了,但是在追求 Web 服务的极致性能时还有一些反向代理的配置能起到事半功倍的效果。本文将简单介绍 Nginx 作为反向代理时选择 HTTP 协议的版本。
Nginx 与上游服务连接时默认会使用 HTTP/1.0 的协议,通过 proxy_http_version
来进行配置。熟悉 HTTP 协议的会知道 HTTP 从 1.1 版本开始已经支持 TCP 的持久连接(Persistent Connection),开启持久连接意味着可以减少建立 TCP 连接时带来的性能损耗。持久连接的优化不光适用于客户端与服务端之间的连接,同样也适用于代理服务于上游服务之间的连接,因为此时的代理服务同样也是一个 TCP 的客户端。将 proxy_http_version
配置为 1.1 就可以开启代理服务与上游服务的持久连接。
除了配置 Nginx 的 proxy_http_version
为 1.1,也可以在上游服务中显式指定 Connection: keep-alive
在 HTTP/1.0 中开启持久连接。像对于 Node.js 的 HTTP 模块默认就会创建 HTTP/1.1 的服务。
可能有些读者看到这里会想,既然可以选择 HTTP 协议的版本,为什么不直接上 HTTP/2 呢?是的,我原来也有同样的疑问。但实际情况是,代理服务与上游服务不适合使用 HTTP/2,因为 HTTP/2 的多路复用的特性是大量的请求复用一个 TCP 连接,在服务端之间是可以大量建立 TCP 连接的,使用 HTTP/2 就相当于放弃了建立大量 TCP 连接的优势,反而会让性能下降。有兴趣的可以看看 Use HTTP/2.0 between nginx reverse-proxy and backend webserver – Server Fault。
“Nginx 作为反向代理的优化点(一)”目前一条评论