Nginx 默认剥离 Connection 头导致后端无法感知 Keep-Alive,需在 upstream 中启用 keepalive 连接池,并在 location 中设 proxy_http_version 1.1 和 proxy_set_header Connection "" 才能真正复用 TCP 连接。

Nginx 默认会剥离或忽略某些 HTTP 头部(尤其是 Connection: keep-alive),导致后端服务无法感知 Keep-Alive 意图,从而退化为短连接。这不是“丢失”,而是 Nginx 主动干预的结果——它为了自身连接管理需要,会重写或清除与连接控制相关的头部。要让后端真正复用 TCP 连接,关键不是“保留原始 Keep-Alive 头”,而是主动声明并维持 HTTP/1.1 长连接通道,并确保 Nginx 与后端之间形成可复用的连接池。
以下配置要点直击问题本质:
启用 upstream 级 Keep-Alive 连接池
Nginx 的 upstream 块必须显式启用长连接支持,否则每个请求都会新建 TCP 连接(即使后端支持 HTTP/1.1):
upstream backend_server {
server 10.0.0.10:8080;
keepalive 32; # 连接池最大空闲连接数
keepalive_requests 1000; # 单个连接最多处理请求数(防老化)
keepalive_timeout 60s; # 空闲连接保持时间
}
⚠️ 注意:
keepalive指令必须放在upstream块内,且不能与ip_hash、hash等会话绑定策略共存(除非使用keepalive兼容版本如 1.15.3+)。
在 location 中强制 HTTP/1.1 并清理 Connection 头
Nginx 默认以 HTTP/1.0 向后端发起请求,并附带 Connection: close。需覆盖为 HTTP/1.1,并交由 Nginx 自行管理连接生命周期:
location /api/ {
proxy_pass http://backend_server;
proxy_http_version 1.1; # 强制使用 HTTP/1.1(Keep-Alive 默认启用)
proxy_set_header Connection ""; # 清空客户端传来的 Connection 头,避免干扰
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
-
proxy_http_version 1.1是前提,没有它,keepalive不生效; -
proxy_set_header Connection ""表示不透传原始Connection头(包括keep-alive或close),由 Nginx 根据连接池状态自主决定是否复用。
验证后端是否实际复用连接
仅配对 Nginx 不代表后端一定复用。需确认:
- 后端服务监听端口支持 HTTP/1.1(如 Tomcat 默认支持,Node.js 的
http.Server也默认开启); - 后端未主动关闭连接(例如 Spring Boot 中
server.connection-timeout=-1为推荐设置); - 使用
ss -tnp | grep :8080 | grep ESTAB观察后端机器上到 Nginx 的 ESTABLISHED 连接是否稳定在几十个而非瞬时飙升后快速消失。
补充:避免因超时导致连接提前中断
若后端响应慢或存在长轮询,还需同步调大超时参数:
proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
这些值应略小于 upstream keepalive_timeout(如设为 60s,后者建议 75s),确保连接在空闲期被 Nginx 主动回收,而非等待后端超时断开。
不复杂但容易忽略











