Nginx+Gateway+Tomcat 三层超时最终归档配置(生产可用)
适配场景
后端业务最大耗时:20分钟(1200s)
优化折中方案:proxy_send_timeout=600s(兼顾大文件上传容错 + 僵尸连接快速回收)
解决问题:504 网关超时、长连接僵连接、PrematureCloseException 断连异常
一、核心硬性时序规则(严禁颠倒)
Nginx proxy_read_timeout(1220s) > Gateway response-timeout(1210s) > 业务最大耗时(1200s)
二、Nginx 配置(完整可直接复制)
2.1 代理超时配置
nginx
location / {
proxy_pass http://你的gateway地址:端口;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 核心三层超时
proxy_connect_timeout 30s;
proxy_send_timeout 600s;
proxy_read_timeout 1220s;
# TCP保活优化:快速清理僵死/半开连接,抵消长超时隐患
proxy_socket_keepalive on;
tcp_keepalive_time 120;
tcp_keepalive_intvl 30;
tcp_keepalive_probes 3;
}
2.2 Nginx 参数详解表
| 参数 | 配置值 | 流向/作用 | 核心说明 & 注意事项 |
|---|---|---|---|
| proxy_connect_timeout | 30s | Nginx 连接 Gateway 建连超时 | 内网充足,只管控TCP握手,不影响业务耗时 |
| proxy_send_timeout | 600s(10分钟) | 上行发送空闲间隔超时 | 关键逻辑:仅上传未完成卡顿生效;普通请求5秒发完body后,该计时器自动失效,不会误伤后端慢计算 |
| proxy_read_timeout | 1220s | 下行响应空闲间隔超时 | 全局最大兜底,专门适配20分钟超长业务处理 |
2.3 Nginx 生效命令
bash
nginx -t # 校验配置
nginx -s reload # 平滑重载
三、Spring Cloud Gateway 配置(完整可直接复制)
3.1 Gateway YAML 配置
yaml
spring:
cloud:
gateway:
httpclient:
connect-timeout: 30000
response-timeout: 1210s
max-in-memory-size: 200MB
pool:
max-idle-time: 15s
eviction-interval: 10s
validate-after-inactivity: 10000
3.2 Gateway 参数详解表
| 参数 | 值 | 单位 | 说明 |
|---|---|---|---|
| connect-timeout | 30000 | ms | 连接Tomcat TCP握手超时,内网足够 |
| response-timeout | 1210s | s | 请求全局总超时,严格小于Nginx read超时 |
| max-in-memory-size | 200MB | - | 大文件内存缓冲阈值,无Body读取过滤器可删除 |
| max-idle-time | 15s | s | 网关空闲连接回收时间,必须 < Tomcat 60s |
| eviction-interval | 10s | s | 定时清理过期连接 |
| validate-after-inactivity | 10000 | ms | 闲置10s复用前探活,杜绝僵连接报错(纯数字,不带s) |
四、Tomcat 后端配置(完整可直接复制)
4.1 Tomcat YAML 配置
yaml
server:
port: ${gaia.services.server.port}
servlet:
encoding:
enabled: true
force: true
charset: utf-8
tomcat:
max-connections: 10000
threads:
max: 800
min-spare: 100
accept-count: 100
connection-timeout: 20000
keep-alive-timeout: 60s
4.2 Tomcat 参数详解表
| 参数 | 值 | 作用说明 |
|---|---|---|
| max-connections | 10000 | Tomcat最大TCP连接总数,容量充足 |
| threads.max | 800 | 最大业务线程,防止长耗时接口占满线程雪崩 |
| threads.min-spare | 100 | 常驻空闲线程,应对突发流量 |
| accept-count | 100 | 线程满后TCP排队队列 |
| connection-timeout | 20000 | 建连后首包超时,只清理空连接,不影响长请求 |
| keep-alive-timeout | 60s | 核心时序:后端空闲60s关闭,大于网关15s,杜绝僵连接 |
五、核心答疑归档(关键误区统一说明)
Q1:请求5秒发完,后端计算20分钟,会被 proxy_send_timeout 600s 误杀吗?
不会。
Nginx 通过 Content-Length / chunked 结束标记判定 body 发送完成。
上行一旦完成,proxy_send_timeout 计时器直接失效,后续只由 proxy_read_timeout 管控。
Q2:为什么 send 设置 600s 而不是 1220s?
折中最优解:
-
600s 足够覆盖大文件上传弱网/暂停卡顿
-
相比20分钟,僵尸连接、半开连接回收更快,资源更健康
Q3:长连接不报错的核心原理?
网关主动回收空闲连接(15s) < 后端Tomcat回收空闲连接(60s)
永远不会出现:后端关连接、网关还拿着死连接复用的场景,彻底解决 PrematureCloseException
六、上线验证步骤
-
Nginx:
nginx -t校验 →nginx -s reload重载 -
重启 Gateway、后端服务,使YAML超时配置生效
-
验证两个核心场景:
-
小参数快速提交 + 后端20分钟慢计算 = 无504
-
大文件上传 + 中途停顿数分钟 = 连接不断开
-
(注:部分内容可能由 AI 生成)