proxy_timeout仅控制tcp/udp代理中已建连后的空闲超时,计时起点为三次握手完成、终点为连续无数据收发,超时即断连;必须置于stream块内,不适用于http代理。

proxy_timeout 不是用来控制“全链路”超时的,它只管 TCP/UDP 代理中连接建立后、完全静默无数据收发的那一段空闲时间。想靠它覆盖建连、发请求、等响应、传给客户端等所有环节,会误判问题、调优失效。
它专属于 stream 模块,必须写在 stream { ... } 块里,不是 HTTP 代理用的参数。下面分三块讲清楚怎么配、为什么这么配、容易踩哪些坑。
proxy_timeout 真正管什么
- 控制 Nginx 与上游(比如数据库、Redis、自定义 TCP 服务)之间 TCP 连接的最大空闲时长
- 计时起点:TCP 连接已成功建立(三次握手完成)
- 计时终点:连续
proxy_timeout秒内,上下游之间一个字节都没收发 - 超时动作:Nginx 主动关闭该连接,释放 fd 和 worker 资源
- 它不参与:DNS 解析、TCP 建连(那是
proxy_connect_timeout)、SSL 握手、应用层协议交互、客户端侧连接管理
简单说:只要这条 TCP 链路上“没人说话”,静默超过设定值,Nginx 就断掉它。
正确配置位置和写法
必须放在 stream 块内,不能写在 http 或 location 里:
stream {
upstream mysql_backend {
server 192.168.1.10:3306;
server 192.168.1.11:3306;
}
server {
listen 3307;
proxy_pass mysql_backend;
proxy_timeout 1h; # 关键:1小时内无数据即断开
proxy_connect_timeout 5s; # stream 模块也支持这个,控制建连阶段
}
}
- 单位支持
s(秒)、m(分)、h(小时),如30s、5m、1h - 不写单位(如
30)会被忽略或报错 - 可以在
server或upstream块里设,但server级别优先级更高
合理取值建议与协同要点
- 默认是 10 分钟,对长连接服务(如 MySQL、MQTT、游戏网关)通常太短
- 数据库代理常见值:30m~2h,取决于后端连接池空闲回收策略
-
心跳保活场景:设为略大于后端心跳间隔(如后端每 45s 发一次心跳,
proxy_timeout 60s) -
无心跳的纯长连接:可设为
0(禁用空闲断开),但务必确认后端有对应兜底机制,否则易堆积僵死连接 - 必须配合
proxy_connect_timeout:它管建连,proxy_timeout管建连后的静默,两者一前一后才完整 - 不需要也不应该和
proxy_read_timeout混用——后者是 HTTP 模块参数,在stream中无效
注意:如果你实际用的是 HTTP 代理(比如反向代理 Web 服务),那你要调的是 proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout,而不是 proxy_timeout。强行在 http 块里写 proxy_timeout,Nginx 会直接报错或静默忽略。











