proxy_socket_keepalive 是 Nginx 与 upstream 间 TCP 连接的保活探测机制,能主动发现并清理被防火墙静默中断的空闲连接,但不防止断连本身;需配合系统级 tcp_keepalive 参数及 proxy_http_version 1.1 等配置协同生效。

proxy_socket_keepalive 是什么,它真能防防火墙断连?
proxy_socket_keepalive 是 Nginx 1.15.3+ 引入的 upstream 指令,作用于 Nginx 与后端服务器(upstream)之间的 TCP 连接,**不是**客户端到 Nginx 的连接。它控制的是 Nginx 主动向后端发 TCP keepalive 探测包的行为。
物理防火墙(尤其是企业级状态检测防火墙、云 SLB)常在空闲超时后静默丢弃连接,不发 FIN/RST,导致上层协议感知不到断连,直到下次发包才报 Connection reset by peer 或 Broken pipe。此时仅靠应用层心跳或 proxy_read_timeout 无效——因为连接早已在中间被掐断,Nginx 还以为它活着。
启用 proxy_socket_keepalive 后,Nginx 会按系统 tcp_keepalive_* 参数(或显式覆盖)发送探测包,一旦收到 RST 或超时无响应,立即关闭该 socket,避免后续请求复用坏连接。
注意:它对「客户端 → Nginx」链路无效;防不住客户端侧 NAT/防火墙断连;也不能替代 WebSocket 心跳。
如何正确配置 proxy_socket_keepalive?关键参数和坑点
必须放在 upstream 块内,且仅对 HTTP/1.1 和 gRPC 等长连接后端生效(对 FastCGI、uWSGI 无效):
upstream backend {
server 10.0.1.5:8080;
proxy_socket_keepalive on; # 开启探测
# 可选:覆盖系统默认值(单位:秒)
# proxy_socket_keepalive on 30s 10s 6; # time interval probes
}常见错误配置:
阿里百炼大模型平台多人共享账号用量统计代理服务。解决公司共用账号时无法区分个人用量的问题。适用场景:1)部署用量统计代理;2)统计多人Token用量和调用次数;3)管理大模型API调用配额。
- 写在
server或location块里 —— 语法错误,nginx -t直接失败 - 误以为开启后就能“保活”所有连接 —— 它只探测并清理死连接,不阻止防火墙切断,只是更快发现
- 未同步调大系统级 keepalive 参数 —— 即使 Nginx 开了,若内核
net.ipv4.tcp_keepalive_time是默认 7200s,探测间隔太长,仍赶不上防火墙 30–300s 的空闲超时 - 后端服务本身禁用了 keepalive(如某些 Java 应用设了
SO_KEEPALIVE=false)—— Nginx 发出的探测包会被直接丢弃,无法触发断连识别
配套必须改的系统参数和 Nginx 其他 timeout
单开 proxy_socket_keepalive 效果有限,需组合调整:
- 内核参数(建议写入
/etc/sysctl.conf):net.ipv4.tcp_keepalive_time = 60net.ipv4.tcp_keepalive_intvl = 10net.ipv4.tcp_keepalive_probes = 3
即:空闲 60s 后开始探测,每 10s 一次,连续 3 次无响应则判定断连 → 总共约 90s 内可感知 - Nginx upstream 层 timeout:
proxy_connect_timeout 10s(建连超时)proxy_send_timeout 30s(发包超时,防大包卡住)proxy_read_timeout 300s(重点!不能小于 keepalive 探测周期,否则可能在探测前就被 proxy_read_timeout 干掉) - 务必关闭
proxy_buffering on(WebSocket 或流式响应场景)—— 否则响应体被缓存,Nginx 不会及时向客户端转发数据,导致“看似没流量”,加速防火墙切断
验证是否生效:从抓包和日志看真实行为
最直接的方式是用 tcpdump 抓 Nginx 与后端之间的包:
tcpdump -i any host 10.0.1.5 and port 8080 -nn -A
看到类似输出即表示生效:... .P.. ... ACK PSH [TCP segment of a reassembled PDU](正常业务包)... ..K. ... ACK [TCP Keep-Alive](keepalive 探测包)
同时检查 Nginx error log:
若出现 upstream prematurely closed connection while reading response header from upstream 频次下降,且新增 recv() failed (104: Connection reset by peer) while connecting to upstream,说明探测成功捕获了被防火墙干掉的连接,并触发了重试逻辑。
容易忽略的一点:这个机制依赖 TCP 层探测,对 UDP 后端(如 DNS、Syslog)完全无效;对 TLS 终止在 Nginx 的场景,proxy_socket_keepalive 作用于解密后的明文连接,依然有效。


















