fastcgi_read_timeout必须置于server或location块中,写在http块会报错;需同步配置fastcgi_connect_timeout、fastcgi_send_timeout,并确保三者均不小于php-fpm的request_terminate_timeout。

fastcgi_read_timeout 必须写在 location 或 server 块里
直接在 http 块里写 fastcgi_read_timeout 会导致 Nginx 启动失败,错误信息是:"fastcgi_read_timeout" directive is not allowed here。它只接受出现在 server 或更细粒度的 location 块中。
最稳妥的做法是定位到实际处理 PHP 的 location ~ \.php$ 块内配置,避免影响静态资源或其他非 PHP 路径:
- 别在
http或upstream块里写,语法直接报错 - 放在
server块里虽合法,但会全局生效,可能掩盖某些路径的真实瓶颈 - 推荐只在匹配
.php$的location中设置,例如导出接口专用路径可单独再加一层嵌套
三个 FastCGI timeout 参数不能只调一个
fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout 各管一段,缺一不可:
-
fastcgi_connect_timeout:Nginx 连上 PHP-FPM socket 的时间上限,默认 60s;跨机房或冷启动服务才需调大 -
fastcgi_send_timeout:Nginx 把整个请求(header + body)发给 PHP-FPM 的耗时上限;大文件上传卡在“发请求”阶段时才需要动它 -
fastcgi_read_timeout:PHP-FPM 执行完并把响应返回给 Nginx 的全程耗时上限;99% 的 504 错误都由它触发
典型长任务场景(如报表导出)建议同步设为:
fastcgi_connect_timeout 30; fastcgi_send_timeout 300; fastcgi_read_timeout 600;
必须和 PHP 层超时对齐,否则 Nginx 先断连
Nginx 的 fastcgi_read_timeout 如果小于 PHP-FPM 的 request_terminate_timeout(或 max_execution_time),Nginx 会在 PHP 还没报错前就主动关闭连接,导致错误日志里看不到 PHP 真实异常。
- 检查
/etc/php/*/fpm/php.ini中的max_execution_time,至少设为和fastcgi_read_timeout相同值 - 再确认
/etc/php/*/fpm/pool.d/www.conf中的request_terminate_timeout,它优先级更高,必须 ≥ 前两者 - 改完 PHP 配置后,记得执行
sudo systemctl reload php*-fpm
proxy_* 参数对 PHP-FPM 完全无效
只要用了 fastcgi_pass(比如 fastcgi_pass unix:/var/run/php/php8.1-fpm.sock),所有 proxy_* 系列参数(如 proxy_read_timeout)都不起作用。这是协议层决定的:FastCGI 和 HTTP 代理是两套独立通道。
- 不要在 PHP location 块里写
proxy_read_timeout,它会被忽略 - 也不要指望改了
http块里的proxy_read_timeout能缓解 PHP 超时 - 检查配置是否生效,最简单方式是故意设一个极小值(如 1s),然后访问一个 sleep(2) 的 PHP 脚本,看是否稳定返回 504
实际生效的关键就两条:位置对(location ~ .php$)、配对齐(Nginx + PHP-FPM + php.ini 三者 timeout 值要形成递进关系)。漏掉任意一环,504 就照常出现。











