504 gateway timeout 若日志无超时记录但频繁出现 upstream queue full、no live upstreams 或 server reached pm.max_children,通常是 php-fpm 进程池耗尽所致;应先检查活跃 worker 数与 pm.max_children 对比,并通过 fpm 状态页确认 active processes 是否长期打满,再临时扩容、切换 dynamic 模式、重启清理,同时启用慢日志定位长驻请求,并收紧 nginx 和 fpm 超时参数防止单请求霸占资源。

504 Gateway Timeout 出现时如果日志里没有超时记录,但反复看到 upstream queue full、no live upstreams 或 server reached pm.max_children 这类提示,大概率不是脚本慢,而是 PHP-FPM 工作进程全部被占满、新请求只能排队或直接被 Nginx 拒绝——这是典型的“进程池耗尽型 504”。
确认是否真为进程数不足
先别急着调超时,用两行命令快速验证:
-
查当前活跃 worker 数:
ps aux | grep 'php-fpm.*www' | grep -v grep | wc -l(对比你设的pm.max_children) -
看 FPM 状态页:确保已开启
pm.status_path = /status,然后访问http://你的站点/status?full,重点关注active processes和max active processes是否长期打满
立即缓解:临时扩容 + 清理积压
若确认是满负荷,优先做三件事稳住服务:
-
临时提高 pm.max_children:编辑对应版本的
www.conf(如~/.phpenv/versions/8.1.0/etc/php-fpm.d/www.conf),把pm.max_children从默认 32 提到 64 或 96(注意留内存余量,每个 worker 约占 20–40MB) -
切换为动态管理模式:把
pm = static改成pm = dynamic,并设置合理区间:pm.start_servers = 10pm.min_spare_servers = 5pm.max_spare_servers = 20pm.max_children = 64 -
重启 FPM 并清空连接队列:执行
~/.phpenv/bin/php-fpm --stop && ~/.phpenv/bin/php-fpm,强制释放所有僵死连接
根治关键:定位并清理“长驻型请求”
进程耗尽很少是正常流量导致,多由以下几类请求长期霸占 worker:
-
未设超时的远程调用:比如
file_get_contents('http://xxx')或curl_exec()缺少CURLOPT_TIMEOUT,卡在 DNS 解析或对方无响应 -
数据库锁或慢查询:一个
SELECT ... FOR UPDATE没提交,或没加索引的WHERE条件,会让整个事务线程挂起几十秒 -
大文件同步操作:如导出 Excel、生成 PDF、压缩打包等未分块、未异步,且未设
set_time_limit()的阻塞脚本
建议打开 FPM 慢日志:request_slowlog_timeout = 5s,再查 slow.log 就能精准抓出哪几个 URL 或函数在“吃进程”。
配套必须调整的超时参数
光加进程数不够,否则只是把 504 推迟几秒。以下三项必须同步收紧,防止单个请求无限占用:
- Nginx 配置中
location ~ \.php(.*)$块内加:fastcgi_read_timeout 120;fastcgi_send_timeout 60;fastcgi_connect_timeout 30; - PHP-FPM 的
www.conf中设:request_terminate_timeout = 120(硬性截断,比max_execution_time更有效) - PHP 脚本内避免
set_time_limit(0),对高风险操作显式设限,例如:set_time_limit(45); // 给 API 请求留余量
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











