FrankenPHP Worker 模式需借助外部协调与轮询实现定时任务:推荐非阻塞时间判断、系统 cron 触发通信、或集成 async-scheduler 等第三方调度器,并注意异常捕获、分布式锁及内存泄漏规避。

FrankenPHP 的 Worker 模式本身不内置定时任务调度能力,但你可以通过外部协调 + PHP 进程常驻 + 时间轮询的方式,在 Worker 中安全、低开销地实现定时逻辑。
利用 Worker 生命周期主动轮询
Worker 启动后长期运行,适合在主循环中嵌入轻量级时间判断。关键点是避免 sleep 阻塞整个协程(尤其使用 Swoole 或 ReactPHP 时),推荐用非阻塞等待或微秒级轮询 + 条件触发:
- 在
handle()或主事件循环中,每次迭代检查当前时间是否到达预定执行点(如每分钟整点、每5秒) - 用
microtime(true)记录上一次执行时间,结合间隔计算是否该触发,避免依赖系统 cron - 任务逻辑应尽量短小,耗时操作建议投递到异步队列(如 Redis List + background worker)或 fork 子进程处理
配合系统 Cron 触发 Worker 通信
更稳妥的做法是让系统 cron 做“触发器”,Worker 做“执行器”:由 crond 定期向 Worker 发送信号或写入共享介质(如 Redis、Unix Socket、文件锁),Worker 在循环中监听并响应:
- 例如:cron 每分钟执行
redis-cli publish frankenphp:tick "now" - Worker 使用
Redis::subscribe()或轮询BRPOP监听频道/队列,收到消息即执行对应任务 - 优势是精度可控、不占用 Worker CPU、与 FrankenPHP 进程模型解耦,也便于横向扩展多个 Worker 实例
用第三方库封装调度逻辑(推荐)
直接集成成熟调度器可减少重复造轮子。例如使用 async-scheduler(基于 Amp)或 Symfony Console + Process 配合信号管理:
立即学习“PHP免费学习笔记(深入)”;
- 在 Worker 初始化阶段启动一个独立的调度协程,注册回调函数(如
$scheduler->addPeriodicCallback(60, fn() => doBackup())) - 确保调度器与 FrankenPHP 的事件循环兼容(如基于
Amp\Loop或Swoole\Event) - 注意内存泄漏:闭包引用 $this 或长生命周期对象时需手动清理
注意事项与避坑点
Worker 是常驻进程,定时逻辑容易因异常中断或状态累积出错:
- 所有定时逻辑必须包裹
try/catch,失败不中断主循环 - 避免在定时回调中直接调用
exit()或die(),改用Worker::stop()或抛出可捕获异常 - 多实例部署时,若任务不可重复执行(如清理日志),需加分布式锁(Redis SETNX + TTL)
- 开发阶段可用
var_dump(date('H:i:s'))打印时间戳验证触发节奏,上线后替换为日志记录



















