
504 错误不是 Nginx 自身挂了,而是它等不到后端响应——问题一定出在「Nginx → 后端」这一段链路上,排查必须沿着这个方向层层向内。
查 Nginx error.log 里有没有 upstream timed out 或 Connection timed out
这是最直接的证据。别只看 access.log,error.log 才记录真实失败原因:
-
upstream timed out (110: Connection timed out) while reading response header from upstream→ 后端根本没发回任何响应头,大概率是后端进程卡死、未启动,或被防火墙拦截 -
upstream prematurely closed connection→ 后端主动断开了连接,常见于 PHP-FPM worker 崩溃、Node.js 进程退出、Java 应用 OOM - 日志里出现大量重复的同一 upstream 地址失败 → 先盯死那个地址对应的服务,别分散精力
确认后端服务是否真在监听且可连通
Nginx 配置里写的 fastcgi_pass 127.0.0.1:9000 或 proxy_pass http://10.0.0.5:8080,不等于后端真在那里干活:
- 用
ss -tlnp | grep :9000(PHP-FPM)或ss -tlnp | grep :8080(Java/Node)确认端口是否被对应进程监听 - 用
curl -v http://127.0.0.1:8080/health或echo -e "GET / HTTP/1.0\r\n\r\n" | nc 127.0.0.1 9000绕过 Nginx 直连测试,看能否拿到响应 - 如果后端是 Unix socket(如
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock),检查文件是否存在、权限是否为www-data可读写
比对 Nginx 和后端各自的超时设置是否匹配
504 是 Nginx 单方面放弃等待的结果,但它放弃的时间点,必须比后端实际能撑住的时间更长,否则永远等不到返回:
- PHP-FPM 场景:Nginx 的
fastcgi_read_timeout必须 大于 PHP-FPM 的request_terminate_timeout(若设为 0 则忽略此条);同时max_execution_time在 php.ini 中仅对 CLI 有效,FPM 下不起作用 - Proxy 场景(如 Node/Java):Nginx 的
proxy_read_timeout必须 > 后端应用自身的请求处理超时(如 Express 的server.timeout、Spring Boot 的server.tomcat.connection-timeout) - 常见陷阱:
proxy_connect_timeout设太小(如 5s),会导致高延迟网络下建连失败,但错误日志通常显示connection refused而非 504,别混淆
检查系统级资源是否耗尽
即使后端进程活着、端口开着、配置也对,仍可能因底层资源不足导致请求无声卡住:
- 执行
df -h看磁盘是否满(尤其是/var/log或 PHP-FPM 的slowlog目录),满盘会直接阻塞写入型请求 - 执行
free -h和cat /proc/meminfo | grep -i "oom\|commit",OOM Killer 若已干掉 PHP-FPM worker,systemctl status php-fpm可能显示 “exited” 但没报错 - 执行
ulimit -n和cat /proc/$(pgrep nginx)/limits | grep "Max open files",若 Nginx worker 打开的文件描述符接近上限,新请求无法建立连接,表现为批量 504
真正麻烦的 504 往往不出现在压测时,而藏在慢查询、锁表、第三方 API 偶发延迟这些“看起来不该超时”的地方——日志里没报错、进程没退出、连接数也没爆,但就是卡在某一次 read() 调用上不动。这时候得靠 strace -p $(pgrep -f 'php-fpm: pool www') 或 tcpdump -i lo port 9000 抓包,看数据到底停在哪一环。

















