Nginx stream模块TCP长连接可靠性需从连接建立、维持、探测、故障切换四层面协同优化:启用upstream keepalive并调优proxy_timeout,配合系统tcp_keepalive参数;透传客户端IP需用PROXY协议或透明代理;通过health_check或max_fails/fail_timeout实现主动探测与故障转移;并限制连接数、关闭缓冲、调大系统资源上限。

在 Nginx 中用 stream 模块做 TCP 代理时,长连接的可靠性不单靠“开启 keepalive”就能保障,而是需要从连接建立、维持、探测、故障切换四个层面协同优化。TCP 层没有 HTTP 的语义头可依赖,所以必须更精细地控制底层连接行为。
启用并调优 stream 级 keepalive
stream 模块本身不提供类似 HTTP 的 keepalive_timeout,但可通过 tcp_keepalive 系统级参数 + Nginx 的 proxy_timeout 组合控制:
- 在
stream块中为 upstream 显式启用连接复用:
upstream backend {<br> server 10.0.1.100:8080;<br> keepalive 200;<br>}
该值表示 Nginx 最多缓存 200 个空闲连接供后续请求复用,避免频繁建连; - 配合设置
proxy_timeout 60s;(在 location 或 server 块内),控制代理连接空闲超时时间,防止后端静默断连后 Nginx 还持有无效句柄; - 操作系统层需同步调整:
在/etc/sysctl.conf中启用 TCP keepalive 并缩短探测周期:net.ipv4.tcp_keepalive_time = 600<br>net.ipv4.tcp_keepalive_intvl = 30<br>net.ipv4.tcp_keepalive_probes = 3
这样可在连接异常挂死后约 690 秒内主动探活并清理。
透传客户端真实 IP 并规避 NAT 失效
TCP 代理默认不修改 IP 包,但若中间经过 SNAT 或负载均衡器,后端可能看到的是 Nginx 的内网 IP。要确保业务逻辑(如风控、限流)基于真实客户端 IP 工作:
- 使用
proxy_protocol协议:在监听端口启用,并要求后端服务支持解析 PROXY 协议头;server {<br> listen 8000 proxy_protocol;<br> proxy_pass backend;<br>} - 若后端不支持 PROXY 协议,且网络允许,改用 透明代理模式(需 root 权限 + iptables 配合),让后端直接看到源 IP,避免地址转换带来的连接状态错乱;
- 禁用
bind或指定bind 10.0.1.200:8000 transparent;(仅限 Linux),配合set_real_ip_from在 stream 块中不可用,故透明代理是更可靠的选择。
配置健康检查与快速故障转移
TCP 层无 HTTP 状态码,Nginx 默认只做被动连接失败检测。要提升长连接场景下的可用性,需主动探测:
- 在 upstream 中启用
health_check(需商业版或 OpenResty),或用开源替代方案:
通过nginx-plus的match块定义 TCP 探针,例如发送固定字节并等待响应; - 更通用的做法:搭配外部工具(如
consul-template或keepalived)动态更新 upstream 列表,当某节点连续三次 TCP connect 超时(timeout=3s),将其临时摘除; - 设置
max_fails=3 fail_timeout=30s;,让 Nginx 自动屏蔽异常节点,避免长连接持续打到已失联服务上。
限制连接数与防资源耗尽
长连接虽省开销,但会持续占用 fd、内存和端口。未加约束易导致 Nginx 或后端被拖垮:
- 全局限制并发连接:
stream {<br> limit_conn_zone $binary_remote_addr zone=addr:10m;<br> server {<br> listen 8000;<br> limit_conn addr 100;<br> proxy_pass backend;<br> }<br>} - 为每个 upstream 连接设置读写超时:
proxy_timeout 30s;<br>proxy_responses 1;<br>proxy_buffering off;
关闭缓冲可减少内存占用,适合纯转发场景; - 系统级加固:
增大文件描述符上限(ulimit -n 65536)、调整 TIME_WAIT 回收(net.ipv4.tcp_tw_reuse = 1),防止大量短时重连冲击。


















