Nginx 出现 upstream timed out 错误通常是因为 PHP-FPM 处理请求的时间超过了 Nginx 配置的等待阈值。最推荐的处理方向是先查看 PHP 慢日志确认脚本是否卡死,再同步调整 Nginx 的 fastcgi_read_timeout 和 PHP-FPM 的 request_terminate_timeout 参数,风险边界在于盲目调大超时时间可能掩盖代码性能问题。
先说结论:解决 upstream timed out 需要同时检查 Nginx 等待超时设置和 PHP-FPM 执行超时设置,优先排查脚本执行效率。
- 先确认:查看 Nginx 错误日志定位超时具体阶段,检查 PHP-FPM 慢日志确认脚本是否耗时过长。
- 先处理:同步修改 Nginx 配置中的 fastcgi_read_timeout 和 PHP-FPM 配置中的 request_terminate_timeout。
- 再验证:重载服务后复现请求,观察错误日志是否不再出现 504 状态码。
命令速用版
以下命令用于快速检查配置语法和重载服务,操作前请备份配置文件。
nginx -t
systemctl reload nginx
systemctl reload php-fpm
为什么会这样
Nginx 作为反向代理等待 PHP-FPM 响应时,如果 PHP 脚本执行时间超过 Nginx 设定的超时值,Nginx 会主动断开连接并记录 upstream timed out。
这通常涉及两个层面的超时控制:Nginx 侧的 FastCGI 读取超时和 PHP-FPM 侧的请求执行超时。如果 PHP 脚本因数据库查询慢、外部 API 调用卡顿或死循环导致执行时间过长,而 Nginx 配置的等待时间较短,就会触发 504 Gateway Timeout 错误。
分步处理
第一步:检查 Nginx 错误日志
查看 Nginx 错误日志文件,通常位于 /var/log/nginx/error.log,确认错误信息包含 upstream timed out。
第二步:调整 Nginx 超时配置
在 Nginx 配置文件的 location ~ \.php$ 块中,增加或修改 fastcgi_read_timeout 参数。默认值通常较短,可根据业务需求适当延长。
fastcgi_read_timeout 300s;
第三步:调整 PHP-FPM 超时配置
编辑 PHP-FPM 配置文件 php-fpm.conf 或 pool 配置文件 www.conf,查找 request_terminate_timeout 参数。如果该值为 0 表示无限制,建议设置为与 Nginx 超时时间一致或略长。
request_terminate_timeout = 300s
第四步:检查 PHP 慢日志
在 PHP-FPM 配置中开启 slowlog,定位具体哪行代码执行慢。公开资料中没有看到可靠的量化数据说明多少秒算慢,需根据业务逻辑判断。
怎么验证是否生效
重载 Nginx 和 PHP-FPM 服务后,再次访问触发超时的页面。如果页面正常加载且 Nginx 错误日志中不再出现 upstream timed out,说明配置生效。同时检查 PHP-FPM 慢日志,确认是否有脚本被记录为慢查询。
常见坑
1. 只改 Nginx 不改 PHP-FPM:如果 PHP-FPM 先杀死了进程,Nginx 会报 502 Bad Gateway 而不是 504。
2. 超时时间设置过大:过长的超时时间会导致 PHP-FPM 子进程长期被占用,在高并发场景下可能耗尽进程池。
3. 忽略脚本优化:单纯增加超时时间是止血措施,长期应优化 SQL 查询或代码逻辑。
常见问题
upstream timed out 和 502 Bad Gateway 有什么区别?
upstream timed out 对应 504 状态码,表示 PHP-FPM 处理太慢;502 通常表示 PHP-FPM 进程崩溃或连接被拒绝。
php.ini 中的 max_execution_time 会影响这个错误吗?
会,如果 php.ini 中的 max_execution_time 短于 Nginx 超时设置,PHP 脚本会先停止执行,导致 Nginx 收不到完整响应。
socket 连接和 TCP 连接超时配置一样吗?
配置参数一样,但 socket 连接还需检查文件权限和监听路径是否正确,否则会报连接拒绝错误。
参考来源
- Nginx Official Documentation - ngx_http_fastcgi_module - https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
- PHP Official Documentation - php-fpm configuration - https://www.php.net/manual/en/install.fpm.configuration.php