hyperf多进程定时任务突然停止主因是crontab-dispatcher进程退出或被杀,需排查进程存活、系统oom killer、配置注册一致性及信号处理异常。

Hyperf多进程定时任务突然停止,通常不是代码逻辑中断,而是进程本身退出、被杀或未正确拉起。重点排查进程存活状态、系统资源限制、信号处理异常和配置一致性四个层面。
确认crontab-dispatcher进程是否仍在运行
定时任务依赖独立的crontab-dispatcher进程分发任务,它不依附于HTTP Worker,必须常驻。执行以下命令验证:
-
ps aux | grep 'crontab-dispatcher'—— 若无输出,说明进程已退出或从未启动 -
ps aux | grep 'php.*hyperf.php'—— 检查是否有多个php bin/hyperf.php start残留主进程(可能干扰dispatcher) - 若进程存在但任务不触发,立即查
runtime/logs/hyperf.log末尾是否有abnormal exit或Segmentation fault记录
检查系统级资源与OOM Killer干预
凌晨或高负载时段定时任务停摆,大概率是crontab-dispatcher进程被系统OOM Killer强制终止,且不留PHP日志。
- 运行
sudo dmesg -T | grep -i "killed process" | grep -A2 -B2 crontab,重点看时间是否匹配任务停止时刻、进程名是否含php或hyperf - 若无结果,扩大搜索:
sudo dmesg -T | grep -i "oom\|out of memory" - 结合
sudo journalctl -u hyperf.service --since "2026-08-13 02:00:00" -n 50,确认服务退出状态是否为status=137(即被信号9杀死)
验证定时任务配置与进程注册一致性
Hyperf 3.2+ 中,hyperf/crontab组件需显式注册为自定义进程,否则不会随start命令自动拉起。
- 检查
config/autoload/processes.php是否包含Hyperf\Crontab\Process\CrontabDispatcherProcess::class - 确认
config/autoload/crontab.php中'enable' => true且任务类的#[CronJob]注解语法正确(如rule="* * * * *") - 若使用自定义进程管理器(如
ProcessManager),检查是否在boot()阶段提前调用了CrontabManager,导致初始化冲突
排查信号处理与优雅停机干扰
当Kubernetes preStop钩子或手动kill -TERM触发时,若crontab-dispatcher未正确注册ProcessStopHandler,可能被提前终止而不执行完当前周期任务。
- 检查
config/autoload/signal.php中handlers数组是否包含Hyperf\Process\Listener\ProcessStopHandler::class - 在
crontab-dispatcher进程内添加简单日志:于任务类execute()开头写入file_put_contents('/tmp/cron_tick', date('H:i:s') . "\n", FILE_APPEND),观察文件是否持续更新 - 若日志中断且时间点与K8s滚动更新吻合,需调整preStop脚本,避免重复发送SIGTERM











