hyperf无processexit事件,自定义进程崩溃后由processmanager自动拉起;需在onworkerstart中注册register_shutdown_function做退出清理,避免协程死锁。

ProcessExit事件在Hyperf里根本不存在
Hyperf 没有 ProcessExit 事件,也**不提供进程退出时的钩子回调**。你查文档、翻源码、搜 GitHub Issues 都找不到这个事件名——它不属于 Hyperf 的事件系统,也不是 Swoole 的标准事件。试图监听它只会让代码静默失效,连日志都不会打一条。
自定义进程崩溃后自动拉起靠的是AbstractProcess内置机制
Hyperf 的自定义进程(继承 AbstractProcess)默认就带「崩溃自愈」能力,不需要你手动监听或重启。只要进程因未捕获异常、段错误、OOM 等原因退出,主 Server 进程会立刻 fork 新实例补上。这个行为由 Hyperf\Process\ProcessManager 控制,无需额外配置。
- 确保没覆盖
isEnable()方法返回false,否则进程压根不会启动 - 别在
handle()里写死循环 +sleep()且不加任何 I/O 或协程唤醒点,否则触发all coroutines are asleep - deadlock!后进程卡住不动,看起来像“没拉起”,其实是调度器离线了 - 如果用了
nums > 1,一个副本挂了,其他副本照常运行,ps aux | grep YourProcessName可能只看到部分进程,误判为“全挂”
真要干预进程退出,只能靠register_shutdown_function,但必须在onWorkerStart里注册
想在进程退出前做清理(比如关连接、发告警),唯一可靠方式是用 register_shutdown_function,但有个硬约束:它必须在 Swoole 的 onWorkerStart 回调里注册,而不是在全局或构造函数里写一次。因为每个 Worker(含自定义进程)是独立的 Linux 进程,不共享 PHP 执行上下文。
Hyperf 3.2.3于2026年7月30日发布,是3.2分支的官方维护版本,新增支持函数,并修复模型注释、缓存组件文档、数据库模型构建器注释和关联预加载字段等问题。
- 在进程类的
handle()开头加:if (!function_exists('my_shutdown_handler')) { register_shutdown_function('my_shutdown_handler'); } -
my_shutdown_handler内部用error_get_last()判断是否发生致命错误,再决定是否上报或记录$signal和$exitCode - 注意:协程内抛出的
Throwable不会触发 shutdown 函数,得靠go(function () { try { ... } catch {} })包一层
验证进程是否真的“挂了”,别只看ps或process:list
php bin/hyperf.php process:list 显示 “running” 只代表进程注册成功,并不反映当前 handle 循环是否活跃;ps aux 看到进程存在,也不代表它还在执行业务逻辑。真正有效的检查方式是:
- 在
handle()里每 5 秒打一行日志:$this->logger->info('tick @ ' . date('H:i:s')),然后tail -f runtime/logs/*.log看输出是否持续 - 用
strace -p [pid] -e trace=futex,clone,wait4观察是否卡在futex(... FUTEX_WAIT_PRIVATE ...)—— 这说明调度器已离线 - 检查
/proc/[pid]/status中的State字段:如果是T(stopped)或长期Z(zombie),说明进程已不可恢复,依赖自动拉起即可
Hyperf 自定义进程的稳定性不取决于你写了多少兜底逻辑,而在于你有没有避开协程死锁、信号处理错位、以及把 shutdown 钩子注册到错误的作用域里。真正的“修复”,往往是删掉那些自以为聪明的重启代码,然后确认 AbstractProcess 的默认行为正在按预期工作。










