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

如何通过PHP异常触发Supervisor指定退出码?

解决方案:用自定义Exception实现Supervisord不重启PHP Worker

这个问题我之前维护PHP任务队列Worker时也碰到过,核心原因是默认情况下PHP抛出未捕获的Exception(比如RuntimeException)时,进程会以退出码1终止——这个码不在你配置的exitcodes=99,255列表里,所以supervisord还是会按规则重启进程。

要实现用Exception触发“阻止重启”的逻辑,我们可以通过自定义异常类+全局异常捕获的方式,既保持代码的面向对象特性,又能精准控制退出码。

步骤1:定义自定义异常类

首先创建一个专属的异常类,用来标记“需要让supervisord停止重启”的场景:

<?php
class SupervisorStopException extends Exception
{
    // 无需额外逻辑,保持极简即可,也可根据需求自定义构造方法
}

步骤2:在业务逻辑中抛出异常

当满足你设定的“需要终止进程且不重启”的条件时,抛出这个自定义异常:

// 示例:Worker的任务处理逻辑
public function processTask()
{
    // 检查特定条件,比如任务队列关闭、资源耗尽、触发维护模式等
    if ($this->shouldStopWorker()) {
        throw new SupervisorStopException('触发Worker主动终止,Supervisord无需重启');
    }

    // 正常处理任务的逻辑
    $this->handleTask();
}

步骤3:全局捕获异常并指定退出码

接下来在Worker的入口文件中,通过全局异常处理器或包裹主循环的try-catch,捕获自定义异常后以exit(99)终止进程:

方案A:全局异常处理器(推荐,覆盖所有未捕获异常)

<?php
// 注册全局异常处理器
set_exception_handler(function (Throwable $e) {
    if ($e instanceof SupervisorStopException) {
        // 可选:将终止原因写入错误日志,方便后续排查
        fwrite(STDERR, "[主动终止] {$e->getMessage()}" . PHP_EOL);
        exit(99); // 触发Supervisord的不重启规则
    }

    // 其他异常:以退出码1终止,让Supervisord自动重启Worker
    fwrite(STDERR, "[异常重启] {$e->getMessage()}" . PHP_EOL);
    exit(1);
});

// 启动Worker主循环
$worker = new TaskQueueWorker();
$worker->run();

方案B:包裹主循环的try-catch

如果你的Worker有明确的主循环,也可以直接用try-catch包裹:

<?php
$worker = new TaskQueueWorker();

try {
    while (true) {
        $worker->processTask();
        // 任务间隔休息时间
        sleep(1);
    }
} catch (SupervisorStopException $e) {
    fwrite(STDERR, "[主动终止] {$e->getMessage()}" . PHP_EOL);
    exit(99);
} catch (Exception $e) {
    fwrite(STDERR, "[异常重启] {$e->getMessage()}" . PHP_EOL);
    exit(1);
}

关键注意事项

  1. 保持Supervisord配置不变:确保你的supervisord.conf中依然保留exitcodes=99,255,这样当进程以99退出时,Supervisord会识别为“正常终止,无需重启”。
  2. 区分异常场景:自定义异常只用于“主动要求终止且不重启”的情况,其他业务异常仍以退出码1终止,保证Worker遇到普通错误时能自动重启。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:16:36