Hyperf 中实现周期性任务有四种方法:一、用@Crontab注解声明定时任务;二、封装为命令行指令手动或系统crontab触发;三、基于Swoole Table+Timer自定义调度;四、用Redis ZSet构建分布式定时队列。

如果您在使用 Hyperf 框架开发应用时需要执行周期性任务,例如数据清理、状态同步或报表生成,则需通过其内置的定时任务调度机制来实现。以下是几种可行的实现方法:
一、基于 @Crontab 注解的定时任务
Hyperf 提供了 @Crontab 注解,允许开发者在任意类的方法上声明定时执行逻辑,框架会在启动时自动注册并由协程定时器驱动执行。
1、在项目 app/Command 目录下创建一个新类,例如 DailyReportTask.php。
2、为该类添加 @Crontab 注解,设置 rule="0 0 * * *" 表示每天零点执行。
3、确保该方法被声明为 public 并返回 void,且所在类已通过 @Component 注解注册为容器组件。
4、启动服务前确认 hyperf/crontab 组件已安装,并在 config/autoload/dependencies.php 中注入 CrontabManager。
二、通过命令行手动触发定时任务
Hyperf 支持将定时任务封装为可独立运行的命令,便于调试与手动干预,适用于临时执行或非周期性调度场景。
1、执行 php bin/hyperf.php gen:command Task\ManualSyncCommand 生成命令类。
2、在 handle() 方法中编写具体业务逻辑,例如调用数据库同步服务。
3、在终端中运行 php bin/hyperf.php task:manual-sync 手动触发该任务。
4、若需结合系统 crontab 调用,可在 Linux 的 /etc/crontab 中添加类似 0 2 * * * cd /path/to/project && php bin/hyperf.php task:manual-sync >> /dev/null 2>&1 的条目。
三、集成第三方调度器 Swoole\Table + Timer 实现自定义调度
当默认 Crontab 组件无法满足高精度或动态调整需求时,可通过直接操作 Swoole 的 Timer 和 Table 实现轻量级调度中心,支持运行时增删任务。
1、在 ServerProcess 中初始化一个 Swoole\Table 存储任务元信息(如名称、规则、下次执行时间)。
2、使用 swoole_timer_tick 每秒扫描一次 Table,比对当前时间与 next_time 字段。
3、匹配成功后,通过 Container::get() 获取对应任务处理器实例并调用 execute() 方法。
4、执行完毕后更新 Table 中的 next_time 字段,按 cron 表达式解析出下一次触发时间戳。
四、使用 Redis ZSet 构建分布式定时任务队列
在多 Worker 实例部署场景下,需避免重复执行同一任务,利用 Redis 有序集合可实现跨进程协调与延迟调度。
1、将任务序列化后以 UNIX 时间戳为 score 写入 Redis ZSet,键名为 hyperf:delayed:tasks。
2、启动一个常驻协程,每 100ms 执行一次 ZRANGEBYSCORE 查询 score ≤ 当前时间戳的任务。
3、对查出的任务使用 ZREM 原子性移除,防止其他 Worker 重复获取。
4、将任务推入 Hyperf 的 Coroutine\Channel 或交由 AmqpProducer 投递至消息队列进一步处理。











