Nginx 反向代理怎么配置 keepalive 长连接减少握手开销?

文章导读
要在 Nginx 反向代理中启用 keepalive 长连接,核心是在 upstream 块中设置 keepalive 参数,并在 location 块中强制使用 HTTP/1.1 协议且清除 Connection 头。这适用于 Nginx 与后端服务之间频繁通信的场景,能有效减少 TCP 握手开销。
📋 目录
  1. A 核心配置步骤
  2. B 验证长连接是否生效
  3. C 常见坑与排查
  4. D 参考来源
A A

要在 Nginx 反向代理中启用 keepalive 长连接,核心是在 upstream 块中设置 keepalive 参数,并在 location 块中强制使用 HTTP/1.1 协议且清除 Connection 头。这适用于 Nginx 与后端服务之间频繁通信的场景,能有效减少 TCP 握手开销。

先说结论:配置正确后,Nginx 与后端服务之间会复用 TCP 连接,避免频繁握手,但需确保后端服务本身支持并保持长连接。

  • 适合后端响应快且并发较高的场景
  • 先调整 upstream 和 location 配置项
  • 再观察后端连接数及日志变化

核心配置步骤

配置涉及两处关键修改:upstream 块定义连接池,location 块指定协议版本和头信息。请确保 Nginx 版本支持 upstream keepalive(大多数现代版本均支持)。

http {
    upstream backend {
        server 192.168.1.10:8080;
        keepalive 32;  # 设置空闲长连接数量,非最大并发数
    }

    server {
        location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;  # 强制使用 HTTP/1.1
            proxy_set_header Connection "";  # 清除 Connection 头,避免关闭
        }
    }
}

注意:keepalive 数值表示每个 worker 进程维护的空闲连接数。设置过大可能占用过多文件描述符,设置过小则复用效果不明显。通常根据 worker 数量和后端承载能力调整,一般设置为后端实例数的 2-4 倍。

验证长连接是否生效

配置完成后,需通过可靠手段验证 Nginx 与后端之间是否复用了连接。

Nginx 反向代理怎么配置 keepalive 长连接减少握手开销?

1. 避免使用 curl -v 直接验证 upstream 头

curl -v 只能查看客户端到 Nginx 的交互头信息,无法直接看到 Nginx 到后端的请求头。因此,不能仅凭 curl 输出判断 upstream keepalive 是否生效。

2. 使用 tcpdump 抓包分析(推荐)

在 Nginx 服务器上抓包,观察 Nginx 与后端 IP 之间的流量。如果配置生效,多次请求中应看到 Connection: keep-alive 且 TCP 连接未频繁断开重建。

sudo tcpdump -i any -A 'port 8080 and host 192.168.1.10' | grep -i connection

观察输出中是否持续出现 Connection: keep-alive,且同一 TCP 会话中承载了多个 HTTP 请求。

Nginx 反向代理怎么配置 keepalive 长连接减少握手开销?

3. 查看后端应用日志

如果后端服务(如 Tomcat、Go、Node.js)记录了请求头,检查日志中接收到的 Connection 字段。若配置生效,该字段应为空或 keep-alive,而非 close

4. 观察后端连接数

在后端服务器上查看当前建立的 TCP 连接数。如果配置生效,在高并发请求下,活跃连接数应趋于稳定,而不是随请求量线性增长。

ss -ant | grep :8080 | wc -l

常见坑与排查

  • 默认协议版本:如果不显式设置 proxy_http_version 1.1,Nginx 默认可能使用 1.0,导致 keepalive 不生效。建议显式声明。
  • 后端主动关闭:即使 Nginx 配置了长连接,如果后端服务配置了较短的 keepalive 超时时间,或者主动返回 Connection: close,连接仍会被断开。需确保后端也允许长连接。
  • 文件描述符限制:keepalive 连接会占用文件描述符。如果系统 ulimit 设置过小,可能导致 Nginx 无法建立足够的长连接,需检查 worker_connections 及系统限制。
  • 鉴权或特殊 header:某些场景下,如果请求中包含特定 header 导致后端认为必须新建连接,长连接也会失效。需结合后端日志排查。

参考来源