首页 > Technology > 正文

Nginx 504 Gateway Timeout 怎么办?超时优化与排查指南

fenij 2026-07-29 155 Technology

网站突然报 504 Gateway Timeout,说明 Nginx 把请求转给了后端(PHP-FPM、Node、Java 等),但后端在限定时间内没给回结果,Nginx 等不及就报了超时。它和 502 不一样:502 是后端”连不上或者直接挂了”,504 是后端”连上了但太慢”。这篇文章从定位到解决,带你完整走一遍。

504 超时参数速查

参数 位置 默认 → 建议值
proxy_read_timeout nginx.conf 60s → 120s
proxy_connect_timeout nginx.conf 60s → 60s
fastcgi_read_timeout nginx.conf 60s → 300s
max_execution_time php.ini 30 → 300
request_terminate_timeout php-fpm.conf 0 → 300
60s
Nginx 默认超时
🔧
300s
PHP 建议值
📊
504
上游超时

第一步:确认是谁在超时

先看 Nginx 的错误日志,确认到底超时在哪:

tail -50 /var/log/nginx/error.log

典型日志是 upstream timed out (110: Connection timed out) while reading response header from upstream,说明后端处理太慢。再确认一下后端进程还活着没、负载正不正常:

systemctl status php-fpm
top
uptime

要是 CPU 或负载爆了,问题就在后端性能本身;如果负载正常但个别接口超时,多半是某个慢请求(慢 SQL、外部 API 调用)拖住了。

第二步:找到慢在哪里

PHP 环境下把 PHP-FPM 慢日志打开,它能直接把卡住的函数调用栈打印出来:

# php-fpm.d/www.conf
slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 5s

重启 PHP-FPM 之后复现一下问题,去看 slow.log。常见的根因排个序:慢 SQL 查询(缺索引)、调第三方接口没设超时、循环里处理大批量数据、磁盘 IO 瓶颈。数据库这边也可以把 MySQL 慢查询日志打开一起查:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;

第三步:合理调大超时参数(应急)

如果某些请求本来就很耗时(比如报表导出、大文件处理),可以针对性地把 Nginx 超时调大,在对应的 location 或 server 块里加:

proxy_connect_timeout 60s;
proxy_send_timeout    120s;
proxy_read_timeout    120s;
# fastcgi 场景(PHP)用:
fastcgi_read_timeout  120s;

同时确认后端自己的执行时间限制也跟上,否则 Nginx 在那等,PHP 却先掐断了:

; php.ini
max_execution_time = 120
; www.conf
request_terminate_timeout = 120s

改完先 nginx -t 检查语法,再 systemctl reload nginx。注意:调大超时只是止血,把全站超时一股脑改成 300 秒,反而会让慢请求堆积、连接耗尽,故障被放大。

第四步:从根上优化,避免复发

长期方案按优先级做这几件事:给慢 SQL 加索引或改写查询;调第三方接口时设 3–5 秒超时并做降级;耗时任务改成异步队列(用户提交后后台跑,前端轮询结果);热点数据加 Redis 缓存;PHP-FPM 按内存合理调 pm.max_children,别让进程排队。这几样做完,绝大多数 504 都会消失。

常见问题

Q1:504 和 502 到底怎么区分处理?
502 优先查后端进程是不是挂了、端口/套接字对没对上;504 优先查后端为什么这么慢。日志里 connect() failed 指向 502,upstream timed out 指向 504。

Q2:只有个别页面 504,其他都正常,怎么办?
基本可以锁定是那个页面的慢逻辑:把 PHP-FPM 慢日志打开复现一次,直接看卡在哪个函数,通常就是慢 SQL 或外部请求。

Q3:用了 CDN(如 Cloudflare)报 504 怎么排查?
先绕开 CDN 直接打源站 IP 测试:源站正常,就是 CDN 回源超时设置的问题;源站也 504,就按本文流程查源站。

如果按上面几步还没解决,欢迎到 fenij.com 本文下方留言,把你的报错日志和环境说一下,我尽量帮你分析。

排错自查清单

  • ☐ 504 超时参数速查
  • ☐ 第一步:确认是谁在超时:先看 Nginx 的错误日志,确认到底超时在哪:
  • ☐ 第二步:找到慢在哪里:PHP 环境下把 PHP-FPM 慢日志打开,它能直接把卡住的函数调用栈打印出来:
  • ☐ 第三步:合理调大超时参数(应急):如果某些请求本来就很耗时(比如报表导出、大文件处理),可以针对性地把 Nginx 超时调大,在对应的 loca
  • ☐ 第四步:从根上优化,避免复发:长期方案按优先级做这几件事:给慢 SQL 加索引或改写查询;调第三方接口时设 3–5 秒超时并做降级;耗时任务
  • ☐ 常见问题:Q1:504 和 502 到底怎么区分处理?502 优先查后端进程是不是挂了、端口/套接字对没对上;504 优

关键命令速查

  • tail -50 /var/log/nginx/error.log
  • systemctl status php-fpm top uptime
  • # php-fpm.d/www.conf slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s
  • SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 2;
  • proxy_connect_timeout 60s; proxy_send_timeout 120s; proxy_read_timeout 120s; # fastcgi 场景(
  • ; php.ini max_execution_time = 120 ; www.conf request_terminate_timeout = 120s

相关延伸

更系统的排查思路,见 Technology 分类归档

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: