Nginx upstream长连接需在upstream块中配置keepalive并配对proxy_http_version 1.1和proxy_set_header Connection "",否则无效;keepalive_timeout和keepalive_requests仅作用于客户端连接,不影响后端长连接。

keepalive,且配套调整 HTTP 版本和 Connection 头。
upstream keepalive 指令必须配在 server 块外
很多人把 keepalive 写在 location 或 server 块里,Nginx 直接报错:unknown directive "keepalive"。它只允许出现在 upstream 块内部。
-
upstream块必须定义在http块下,不能嵌套在server或location中 - 每个
upstream组只能有一个keepalive N,N 是整数,代表「每个 worker 进程最多缓存多少个空闲长连接到该组中的单台后端」 - 例如
keepalive 32表示:每个 worker 进程对192.168.1.10:8080最多保留 32 个空闲连接;如果后端有 2 台,那总共最多 64 个空闲连接(按 worker 数 × 后端数 × 32 计算)
proxy_http_version 和 proxy_set_header Connection 必须成对出现
仅写 keepalive 32 不生效——Nginx 默认用 HTTP/1.0 转发,而 HTTP/1.0 不支持 Keep-Alive。后端收到请求后直接返回并关闭连接,keepalive 形同虚设。
- 必须加
proxy_http_version 1.1,强制升级协议版本 - 必须加
proxy_set_header Connection "":清空客户端传来的Connection: close或其他值,否则 Nginx 会原样透传,导致后端误判为短连接 - 不需要设置
proxy_set_header Keep-Alive,那是客户端行为,Nginx 作为代理不生成该头
keepalive_timeout 和 keepalive_requests 控制的是客户端连接,不是 upstream
这两个参数常被误认为影响 upstream 长连接,其实它们只管「浏览器 → Nginx」这一段:
-
keepalive_timeout 60s 60s:Nginx 等客户端 60 秒没新请求就关掉连接;第二个 60s 是响应头Keep-Alive: timeout=60的值,提示浏览器别超时 -
keepalive_requests 100:同一个长连接上最多处理 100 个请求,到数即断,防止单连接长期霸占资源 - 它们对「Nginx → 后端」完全无影响。upstream 长连接的生命周期由后端服务自身决定(比如 Tomcat 的
connectionTimeout),Nginx 只负责缓存空闲连接,不主动探测或保活
常见失效原因:后端服务没开启长连接支持
即使 Nginx 配全了,后端仍可能拒绝复用连接。典型表现是 Nginx error log 出现 upstream prematurely closed connection 或连接数始终不下降。
- Node.js(原生 http.Server):默认支持 HTTP/1.1 长连接,但需确保没手动调用
res.end()后又写res.socket.destroy() - Tomcat:检查
server.xml中Connector的connectionTimeout(建议 ≥ 60s)和keepAliveTimeout(若存在) - Go net/http:默认启用长连接,但若 handler 中用了
panic或未 recover,会导致连接异常中断 - 验证方式:用
ss -tnp | grep :8080查看后端端口是否有大量ESTAB连接长时间存在;或抓包看 TCP 层是否复用同一 socket
keepalive 是个“懒缓存”机制:它不主动建连,也不心跳保活,只在连接空闲时暂存,等下次请求命中同一后端时直接复用。真正决定连接能否长久存活的,是后端服务的配置和稳定性。别只盯着 Nginx 参数调优,漏掉后端那一环,所有配置都白搭。


















