504 gateway time-out 根源在于 nginx 与 php-fpm 超时协同失配或资源耗尽:需依序查 nginx 错误日志定位超时类型、核对 fastcgi_read/connect_timeout 与 php-fpm request_terminate_timeout 匹配性、检查 pm.max_children 是否达上限、并用 curl 或 cgi-fcgi 直连验证 php-fpm 可用性。

504 Gateway Time-out 在 Nginx + PHP-FPM 架构中,常不是单纯“后端挂了”,而是 FastCGI 连接链路上某处卡住或超时——比如 Nginx 等不到 PHP-FPM 回应、PHP-FPM 进程被占满、或请求在缓冲区堆积。排查要分层验证,从日志定位、配置比对、到进程与网络实测。
看 Nginx error log 定位超时类型
直接打开 /var/log/nginx/error.log,搜索关键词 upstream timed out 或 fastcgi://。典型报错如下:
- upstream timed out (110: Connection timed out) while reading response header from upstream → Nginx 已连上 PHP-FPM,但迟迟没收到响应头(proxy_read_timeout / fastcgi_read_timeout 触发)
- upstream timed out (110: Connection timed out) while connecting to upstream → Nginx 根本连不上 PHP-FPM(fastcgi_connect_timeout 触发,可能是端口未监听、防火墙拦截、PHP-FPM 崩溃)
- upstream sent too big header → 响应头过大,超出 fastcgi_buffer_size,导致连接中断(间接引发 504)
核对 Nginx 与 PHP-FPM 超时参数是否匹配
FastCGI 超时是“两端协同”的:Nginx 等待时间不能短于 PHP-FPM 实际处理上限,否则必超时。常见不匹配组合:
- Nginx 的 fastcgi_read_timeout 60,但 PHP-FPM 的 request_terminate_timeout=30 → PHP 强制杀掉脚本,Nginx 却还在等,60 秒后报 504
- Nginx 的 fastcgi_connect_timeout 5,而 PHP-FPM 使用 socket 文件且磁盘 I/O 高 → 连接建立慢,5 秒内失败
- PHP 设置了 max_execution_time=30(PHP.ini),但 Nginx 和 PHP-FPM 超时都设为 120 → 表面宽松,实际 PHP 30 秒就终止,Nginx 等满 120 秒才报错,掩盖真实瓶颈
建议统一基准:PHP-FPM 的 request_terminate_timeout ≥ Nginx 的 fastcgi_read_timeout ≥ 应用最大合理耗时(如导出报表设为 300)。
检查 PHP-FPM 进程状态与资源占用
即使配置看似合理,若 PHP-FPM 没有足够空闲进程可用,新请求只能排队等待,最终超时:
- 运行 sudo systemctl status php-fpm 或 sudo service php7.4-fpm status,确认服务 active(running)且无频繁 restart
- 执行 sudo php-fpm -t 验证配置语法;再用 sudo systemctl reload php-fpm 生效
- 查当前活跃子进程数:sudo ss -s | grep "tcp:" 或 sudo netstat -anp | grep :9000 | wc -l(若用 TCP);若接近 pm.max_children,说明进程池已满
- 观察 PHP-FPM 日志(通常在 /var/log/php7.4-fpm.log)是否有 WARNING: [pool www] server reached pm.max_children setting —— 这是关键信号
用 curl 直连 PHP-FPM 验证底层通路
绕过 Nginx,模拟其与 PHP-FPM 的交互,快速判断是代理层问题还是后端本身问题:
- 若 PHP-FPM 监听 TCP(如 127.0.0.1:9000):
curl -v http://127.0.0.1:9000/test.php(需确保 test.php 是简单输出,不含数据库等依赖) - 若监听 Unix socket(如 /run/php/php7.4-fpm.sock):
SCRIPT_NAME=/test.php SCRIPT_FILENAME=/var/www/html/test.php REQUEST_METHOD=GET cgi-fcgi -bind -connect /run/php/php7.4-fpm.sock - 观察是否返回内容、耗时多少。如果直连也超时或拒绝连接,问题 100% 在 PHP-FPM 或系统层面(如 socket 权限、SELinux 限制、内存 OOM Kill)











