Nginx 504 Gateway Timeout:超时链路上每一环怎么查

来源:互联网 时间:2026-09-04

504 和 502 经常被混为一谈,但两者的含义差得远。502 是 Nginx 压根联系不上上游,504 是联系上了、请求也发过去了,可上游迟迟不回话,Nginx 等不下去了。换句话说,502 是后厨关门了,504 是后厨开门营业,只是做菜太慢。

这个区别决定了排查方向完全不同。502 查的是上游在不在,504 查的是上游为什么慢。后者通常是代码里有耗时操作、SQL 没走索引、或者调用了响应很慢的外部接口。

超时参数一共有三层,从外到内依次是 Nginx 的 fastcgi_read_timeout、PHP 的 max_execution_time、FPM 的 request_terminate_timeout,三者默认都是 60 秒。这里有个几乎所有人都会踩的坑:只把最外层调大,里面两层没动,结果照样 504。

规矩是外层必须大于等于内层。你把 Nginx 改成 300 秒,可 PHP 在 30 秒就把脚本掐了,Nginx 等到 300 秒还是拿不到完整响应,照样报错。改超时得顺着链路从内往外改一遍,漏一层就白改。

还有一层很多人不知道:max_execution_time 只计算 PHP 自身的执行时间,不算数据库查询、文件读写、外部接口等待这些 IO 时间。所以一个脚本卡在慢查询上 200 秒,max_execution_time=30 根本拦不住它。真正能硬砍的是 FPM 的 request_terminate_timeout,它是按墙钟时间算的。

# /etc/nginx/conf.d/timeout.conf
# 从内到外配套调整,外层必须 >= 内层

location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
include fastcgi_params;

# 外层:Nginx 等 PHP-FPM 的读超时,默认 60s
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_connect_timeout 10s;

# 后台管理等确实慢的路径单独放宽
# 注意:这里用 PHP_ADMIN_VALUE 覆盖内层参数,只对当前 location 生效
fastcgi_param PHP_ADMIN_VALUE "max_execution_time=300";
}

# /etc/php/8.3/fpm/pool.d/www.conf
; 内层1:PHP 脚本自身执行上限,只算 CPU 时间不算 IO
php_admin_value[max_execution_time] = 300

; 内层2:FPM 按墙钟时间硬杀,这才是真正的兜底
request_terminate_timeout = 300

; 慢日志:超过 5 秒的请求记录调用栈,定位到底卡在哪一行
slowlog = /var/log/php8.3-fpm.slow.log
request_slowlog_timeout = 5s

配置生效前先证明问题确实出在这儿。grep 一下 error.log 里的 timed out 关键字,如果一条都没有,说明压根不是超时,调参数纯属浪费时间。确认之后再动手,改完用 nginx -t 校验、reload 生效。

最后提醒一句:超时调大是给合法的长耗时任务开窗口,不是为了掩盖慢。一个 worker 被长请求占着,就没法服务其他请求,并发一上来整个站都会变慢。所以调完之后该做的正事是开慢日志,找出到底是哪条 SQL、哪个外部调用拖慢的,把它修掉。参数只是止血,慢才是病根。

数据来源:Nginx ngx_http_proxy_module 与 ngx_http_fastcgi_module 官方文档

相关文章

标签:

A5创业网 版权所有