Nginx Pod对特定代理后端随时间变慢出现504超时问题排查
可能的原因及解决建议
1. Nginx到目标后端的长连接未正确配置,导致连接耗尽/僵死
你的配置仅设置了客户端到Nginx的长连接参数(keepalive_timeout等),但完全缺失Nginx到后端服务的长连接管理配置。默认状态下,Nginx不会主动复用与后端的HTTP/1.1连接,随着请求量累积,会产生大量未正确释放的无效连接,最终导致新请求无法建立连接,触发504超时。
解决方法:在http块或对应location块中添加后端长连接配置:
http { # ... 现有配置 ... # 定义后端连接池 upstream servicea { server serviceahost:443; keepalive 32; # 维持32个长连接到该后端 } server { # ... 现有配置 ... location ^~ /a { proxy_pass https://servicea; proxy_http_version 1.1; proxy_set_header Connection ""; # 清除Connection头,启用长连接复用 } } }
2. DNS缓存过期导致Nginx持有后端旧IP
如果serviceahost是域名而非固定IP,Nginx默认会缓存DNS解析结果,且TTL遵循域名的DNS记录设置。若后端服务IP在Nginx运行期间发生变更,Nginx不会自动重新解析,仍会尝试连接旧IP导致超时;而直接访问后端时,本地DNS会获取最新IP,因此表现正常。重启Nginx会触发重新解析,临时恢复服务。
解决方法:
- 配置Nginx定期重新解析DNS:在
http块中添加resolver指令并设置合理TTL(以K8s环境为例):
http { resolver kube-dns.kube-system.svc.cluster.local valid=30s; # ... 现有配置 ... }
- 若为K8s环境,直接使用后端服务的ClusterIP,彻底规避DNS解析问题。
3. 文件句柄耗尽导致无法新建连接
你的配置中worker_rlimit_nofile 1024和worker_connections 1024的上限设置较低。如果针对该后端的请求频繁,且连接未正确释放,会逐渐耗尽文件句柄,导致新请求无法建立连接,出现504。其他后端正常是因为连接数未达到各自上限。
解决方法:
- 提高文件句柄限制:将
worker_rlimit_nofile调整为更大的值,比如worker_rlimit_nofile 4096; - 排查连接泄漏:Nginx运行一段时间后,执行
ss -tulpn | grep nginx查看与serviceahost的连接数,确认是否持续增长。
4. SSL会话缓存异常
由于代理的是HTTPS后端,Nginx的SSL会话缓存可能出现异常:比如缓存满后无法复用会话,每次请求都需重新进行SSL握手,耗时剧增;或者缓存中积累大量无效会话,导致握手失败。这类问题会随时间推移逐渐累积,最终触发超时。
解决方法:
- 调整SSL会话缓存配置,在
http块中添加:
http { ssl_session_cache shared:SSL:10m; # 设置10MB的共享SSL会话缓存 ssl_session_timeout 10m; # 会话超时时间设为10分钟 # ... 现有配置 ... }
- 验证Nginx与后端的SSL协议、加密套件是否兼容,避免握手失败。
内容的提问来源于stack exchange,提问作者user11449724
相关产品推荐
相关产品推荐

