官方文档:https://hyperf.wiki/2.1/#/zh-cn/crontab
定义方法:1、注解定义
2、配置文件定义
特色:提供了秒级定时任务功能
任务属性:
1、name => 定时任务名称
2、rule => 定时任务规则
3、callback => 定时任务回调
4、memo => 定时任务备注
5、enable => 是否生效
配置要求:
1、安装组件 composer require hyperf/crontab
2、启动任务调度进程
2.1、在config/autoload/processes.php 下注册
<?php // config/autoload/processes.php return [ Hyperf\Crontab\Process\CrontabDispatcherProcess::class, ];
2.2、在config/autoload/crontab.php 下配置
<?php return [ // 是否开启定时任务 'enable' => true, ];
注解定义:
<?php namespace App\Task; use Hyperf\Contract\StdoutLoggerInterface; use Hyperf\Crontab\Annotation\Crontab; use Hyperf\Di\Annotation\Inject; /** * @Crontab(name="Foo", rule="* * * * *", callback="execute", memo="这是一个示例的定时任务") */ class FooTask { /** * @Inject() * @var \Hyperf\Contract\StdoutLoggerInterface */ private $logger; public function execute() { $this->logger->info(date('Y-m-d H:i:s', time())); } /** * @Crontab(rule="* * * * * *", memo="foo") */ public function foo() { var_dump('foo'); } }
配置文件定义:
在 config/autoload/crontab.php 配置定时任务
<?php // config/autoload/crontab.php use Hyperf\Crontab\Crontab; return [ 'enable' => true, // 通过配置文件定义的定时任务 'crontab' => [ // Callback类型定时任务(默认) (new Crontab())->setName('Foo')->setRule('30 8 * * *')->setCallback([App\Task\FooTask::class, 'execute'])->setMemo('这是一个示例的定时任务'), ];
注意点:singleton解决任务的并发执行问题,任务永远只会同时运行 1 个。但是这个没法保障任务在集群时重复执行的问题。
问题:假如有多个节点同时请求这个定时任务
方案:redis锁
第一个请求的节点存固定数据,并设置过期时间,其他节点请求时判断存的数据是否存在,存在则跳过
例如:
$redis = make(RedisService::class); if ($redis->exists('key')) return null; $redis->set('key', 1, 60);