必须注册crontabdispatcherprocess进程并启用enable=>true,否则定时任务完全不触发;支持秒级调度需开启enable_millisecond,分布式锁依赖redis配置mutex。

你需要在Hyperf 3.1项目中准确配置并调度定时任务,确保它按预期频率执行、不重复、不遗漏,且能在多实例部署下安全运行。
确认 crontab 组件已安装并启用
执行 composer require hyperf/crontab 安装组件。该组件会自动注册,无需手动添加到依赖注入配置中。
检查 config/autoload/crontab.php 文件是否存在;若不存在,需手动创建,并确保返回数组中 【'enable' => true】。此开关控制整个定时任务系统是否启动,设为 false 时所有任务将被静默忽略。
注意:仅配置 enable => true 不足以让任务运行,还必须注册调度进程——否则服务启动后不会产生任何调度行为。
注册 CrontabDispatcherProcess 自定义进程
打开 config/autoload/processes.php,向返回数组中追加一行:
Hyperf\Crontab\Process\CrontabDispatcherProcess::class
这一步是硬性前提,【缺少该行会导致定时任务完全不触发,且无任何错误提示】。Hyperf 的 Crontab 并非靠 PHP 内置的 pcntl_alarm 或系统 crond 实现,而是依赖此独立协程进程轮询调度。
修改后无需重启 CLI 进程,但必须重启整个 Hyperf 服务(php bin/hyperf.php start)才能生效。
定义定时任务(注解方式)
方法一:使用 @Crontab 注解(推荐)
在 app/Crontab/ 目录下新建类,例如 DailyCleanupTask.php:
声明命名空间与继承关系,添加 #[Crontab] 属性,设置 name、rule、singleton 等关键字段;execute() 方法内写业务逻辑。
方法二:使用配置文件方式(适合动态加载场景)
在 config/autoload/crontab.php 的 'crontab' 键下,用 (new Crontab()) 链式调用构造任务对象,指定 setName()、setRule()、setCallback()(格式为 [类名::class, '方法名'])。
两种方式不能混用于同一任务,否则框架启动时会报错“Duplicate crontab name”。
配置秒级调度与分布式锁
第一步:开启秒级支持
在 config/autoload/crontab.php 中添加配置项:'enable_millisecond' => true。不加此项时,rule 字段即使写成 '*/3 * * * * *' 也会被截断为 5 段,降级为分钟级执行。
第二步:启用单例防并发
在任务类中设置 public array $singleton = true。该选项仅对当前 Worker 进程内有效,防止同一任务在单机多进程下重复执行。
第三步:启用集群级互斥锁
添加 public array $mutex = ['type' => 'redis'],并确保 Redis 连接池已正确配置。此配置使多个 Pod 实例竞争同一把锁,【只有抢到锁的实例才会真正执行任务】。若 Redis 不可用,任务将跳过本次调度,不会阻塞或报错。
验证任务是否正常调度
启动服务:php bin/hyperf.php start。
观察控制台输出,出现类似 [INFO] Crontab manager started with 3 tasks 表示注册成功。
等待下一个整点/整分时刻(如当前时间是 11:01:22,则首个执行在 11:02:00),检查 execute() 中的日志或数据库变更是否如期发生。
注意:Hyperf Crontab 【不会在服务启动瞬间立即执行】,而是严格遵循 cron 规则对齐到最近的合法触发点,这是设计使然,不是 bug。











