Nginx与PHP-FPM超时怎么配:三处超时参数的关系与取舍

    发布时间:2026-09-16 12:32 更新时间:2026-09-16 12:32 阅读量:0

    后台导出报表、批量采集、生成大站点地图,这类耗时任务最容易触发超时。很多人第一反应是把 php.ini 里的 max_execution_time 调到 300,结果页面照样报 504;又有人去改 Nginx,改完变成 502。原因在于请求要穿过三层:Nginx 等 PHP-FPM 应答、PHP-FPM 等 PHP 脚本执行、PHP 自己限制脚本运行时长,任何一层先到点,请求就断。本文把这三处的职责、配置位置和取舍讲清楚,照着调一遍,基本能定位到是哪一层在掐断请求。

    三层超时分别管什么

    第一层是 Nginx。Nginx 把请求通过 FastCGI 协议转给 PHP-FPM 之后,会等待 FPM 返回响应头。等待多久由 fastcgi_read_timeout 决定,默认值 60 秒。注意它统计的是「两次读操作之间的间隔」,不是整个请求的总时长,所以一个持续输出内容的脚本即使跑很久,只要数据在流动就不会被判定超时。同组的还有 fastcgi_connect_timeout(连接 FPM 的超时)和 fastcgi_send_timeout(向 FPM 发送请求的超时),日常调优基本只动 read 这一个。

    第二层是 PHP-FPM。进程池里有个 request_terminate_timeout,它是 FPM 对单个子进程处理单个请求的总时长硬限制,超时后 FPM 会直接 kill 掉这个子进程并记录一条 WARNING 日志。它的作用是兜底:防止某个脚本卡死(比如卡在外部接口或 DNS 解析上)把 worker 长期占住,最终耗尽整个进程池。该参数默认是 0,表示不限制,此时进程会一直等下去,风险要自己评估。

    第三层是 PHP 自身。php.ini 里的 max_execution_time 限制脚本自身的 CPU 执行时间。需要留意的是,它不统计 sleep、数据库等待、网络 IO 等阻塞时间,所以在 Linux 上它管不住「等外部接口」这类场景,真正能拦住这种请求的是 FPM 的 request_terminate_timeout。CLI 模式下该值默认多为 0,即不限制,具体以官方文档和实际环境为准。

    三者的关系可以这样理解:Nginx 决定客户端等不等得到结果,FPM 决定进程被占用多久,PHP 决定脚本自己跑多久。三者都小于任务实际耗时,请求必断;只放开其中一层,另外两层仍会先到点。

    配置写法与推荐取值

    Nginx 侧建议写在 location ~ \.php$ 块里,或者放到单独的 fastcgi_params 片段中统一维护:

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
        fastcgi_connect_timeout 10s;
        fastcgi_send_timeout 120s;
        fastcgi_read_timeout 120s;
    }
    

    PHP-FPM 侧在进程池配置里设置,路径通常是 /www/server/php/版本号/etc/php-fpm.d/www.conf 或 /etc/php-fpm.d/www.conf,以实际环境为准:

    ; 单个请求最长执行 120 秒,超时后由 FPM 结束该子进程
    request_terminate_timeout = 120s
    
    ; 单个子进程处理多少请求后重启,避免内存缓慢增长
    pm.max_requests = 500
    
    ; 慢日志有助于定位卡住的脚本
    request_slowlog_timeout = 10s
    slowlog = /var/log/php-fpm/www-slow.log
    

    php.ini 侧对应调整:

    max_execution_time = 120
    max_input_time = 120
    

    取值思路是「外层略大于内层」。比如任务预计跑 90 秒,PHP 给 120 秒,FPM 给 120 秒,Nginx 给 130 秒。这样正常情况下由 PHP 先结束并返回结果;万一 PHP 卡死,FPM 兜底清理进程;万一 FPM 也异常,Nginx 断开客户端等待,避免浏览器一直转圈。反过来把 Nginx 设得比 FPM 小,请求会先被 Nginx 判定超时,用户看到 504,而后台脚本可能还在跑,白白占用资源。

    改完不生效?按这个顺序排查

    配置改完必须重载才生效,Nginx 用 nginx -t 校验后再 reload,FPM 用 kill -USR2 或 systemctl reload 平滑加载:

    nginx -t && nginx -s reload
    php-fpm -t
    systemctl reload php-fpm
    
    

    确认生效值,注意 FPM 模块可能覆盖 php.ini

    php -i | grep -E "max_execution_time|Loaded Configuration"

    排查时先看错误日志定位是哪一层在报错。Nginx 的错误日志里出现 upstream timed out 通常是 FPM 侧没按时返回;出现 recv() failed 或连接被重置,往往对应 FPM 杀掉了子进程。FPM 日志里出现「execution timed out」就是 request_terminate_timeout 触发的。

    tail -f /var/log/nginx/error.log
    tail -f /var/log/php-fpm/error.log
    
    

    查看进程池是否被占满

    ps aux | grep php-fpm | wc -l

    几个常见坑:一是宝塔等面板会生成独立的 FPM 配置文件,手动改 php.ini 可能被面板覆盖,建议在面板的 PHP 设置里改;二是 PHP 的 set_time_limit() 只能延长不能缩短,且不影响 FPM 的硬限制,两者别混用;三是 Nginx 有多个 location 或 include 了公共片段时,可能出现后者覆盖前者的顺序问题,改完用 nginx -T 输出完整配置核对;四是长任务优先拆成异步队列或后台进程处理,把前端请求控制在秒级返回,比一味加大超时值更稳妥,也更能保护进程池。

    最后提醒一点:超时值放得越大,单个卡死请求占用 worker 的时间就越长,高并发下反而更容易拖垮整站。把 request_slowlog_timeout 打开、定期看慢日志,找出真正耗时的脚本去优化,比单纯调参数更有价值。改完记得压一轮,观察 FPM 的活跃进程数和 504 比例是否回落,再决定是否继续微调。

    继续阅读

    📑 📅
    宝塔PHP扩展装不上怎么办:编译报错与权限排查 2026-09-16
    宝塔面板MySQL与PHP版本切换:兼容性检查、扩展重装与白屏处理 2026-09-16
    WordPress固定链接改版后老链接404:rewrite与301重定向保住收录 2026-09-16
    CDN回源配置怎么填:回源Host、回源协议与真实IP排查 2026-09-16
    宝塔面板计划任务做网站自动备份:数据库与文件打包、异地存储配置 2026-09-15
    WordPress多站点网络搭建:子域名与子目录怎么选、域名映射与迁移注意点 2026-09-16
    域名解析生效慢与解析被劫持:TTL、DNSSEC与本地缓存排查 2026-09-16
    服务器时间不对导致HTTPS报错与定时任务错乱:ntp/chrony校时与宝塔同步配置实操 2026-09-16
    宝塔面板网站防跨站攻击open_basedir怎么配:报错原因、目录放行与多站隔离实践 2026-09-17
    网站被恶意刷流量刷接口怎么办:Nginx限速与IP封禁配置思路 2026-09-17