You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx+PHP-FPM环境下max_execution_time不生效问题排查

Nginx+PHP-FPM超时不一致问题解决方案

为什么max_execution_time=30未生效

  • max_execution_time 仅统计PHP进程实际占用CPU的运行时间,像sleep()、数据库查询、网络请求这类处于等待状态、不消耗CPU资源的操作,不会被计入超时时长。你的测试代码中每次sleep(1)都不会消耗这个超时额度,因此PHP脚本不会在30秒时终止。

核心需求解决方案:客户端断开后终止PHP执行

要避免Nginx返回504后PHP仍做无用功,同时不重启PHP-FPM worker,可通过以下方法实现:

1. 检测客户端连接状态并主动终止脚本

PHP内置connection_aborted()函数可检测客户端(此处为Nginx)是否已断开连接,配合默认的ignore_user_abort(false)(客户端断开时脚本会终止),在脚本的关键节点插入检测逻辑:

// 显式设置客户端断开时终止脚本(默认已开启,可省略但更清晰)
ignore_user_abort(false);

foreach (range(1, 50) as $i) {
    sleep(1);
    
    // 每次循环检测连接状态,断开则终止脚本
    if (connection_aborted()) {
        $this->logger->info('Client disconnected, stopping execution');
        exit;
    }

    if ($i > 40) {
        $this->logger->error('Processing request', ['i' => $i]);
        continue;
    }

    if ($i > 20) {
        $this->logger->warning('Processing request', ['i' => $i]);
        continue;
    }
    $this->logger->info('Processing request', ['i' => $i]);
}

$this->logger->info('Request processed');

原理:Nginx返回504后会主动断开与PHP-FPM的连接,connection_aborted()能捕获这个状态,此时调用exit即可让脚本主动终止,不会影响PHP-FPM worker进程的复用。

2. 生产环境长耗时操作补充优化

  • 数据库查询超时:针对MySQL等数据库,可在执行查询前设置语句超时,例如SET STATEMENT_TIMEOUT=30000;(单位毫秒),让数据库主动终止慢查询,避免PHP长时间等待。
  • 定期检测连接:对于无法设置超时的IO操作,在代码的循环、关键步骤后插入connection_aborted()检测,确保客户端断开后能及时终止脚本。

3. 确保Nginx与PHP的超时配置对齐

  • 调整Nginx的fastcgi_read_timeout(若使用fastcgi_pass连接PHP-FPM)为30秒,与预期超时一致:
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_read_timeout 30s;
        # 其他fastcgi配置...
    }
    

内容的提问来源于stack exchange,提问作者Bogdan Dubyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:53:31