定时任务
目录
【注意】
Hyperf
定时任务本质上是Swoole
拉起的一个进程,并且随着Hyperf
服务启动而启动(可以配置)。- 这里采用
多进程
模式,协程模式暂未使用,暂不总结。
安装依赖
composer require hyperf/crontab
注册执行进程
👇🏻 二选一即可。
自定义执行进程
<?php
declare(strict_types=1);
namespace App\Process;
use Hyperf\Crontab\Process\CrontabDispatcherProcess;
use Hyperf\Process\Annotation\Process;
#[Process(
nums: 1, // 进程数目
name: 'SchedulerProcess', // 进程名称
redirectStdinStdout: false, // 重定向自定义进程的标准输入和输出
pipeType: 2, // 管道类型
enableCoroutine: true // 进程内是否启用协程
)]
class SchedulerProcess extends CrontabDispatcherProcess
{
public string $name = 'scheduler-process';
}
使用系统执行进程
config/autoload/processes.php
<?php
declare(strict_types=1);
return [
// 定时任务调度器进程
Hyperf\Crontab\Process\CrontabDispatcherProcess::class,
];
开启随服务启动
config/autoload/crontab.php
<?php
declare(strict_types=1);
return [
// 是否开启定时任务
'enable' => true,
];
定义任务
定时任务抽象类
<?php
declare(strict_types=1);
namespace App\Scheduler;
use App\Constants\ConstCode;
use Hyperf\Cache\Cache;
use Hyperf\Context\ApplicationContext;
class AbstractScheduler
{
// 定时任务逻辑是否执行(外部变量控制)
protected bool $isRunning;
public function __construct()
{
$cache = ApplicationContext::getContainer()->get(Cache::class);
// 命令行命令 可以开启或关闭该开关 eg: php bin/hyperf crontab:switch start
$isRunning = $cache->get(ConstCode::SCHEDULER_IS_RUNNING_KEY, false);
$this->isRunning = ! ($isRunning === false);
}
}
定时任务
<?php
declare(strict_types=1);
namespace App\Scheduler;
use App\Lib\Log\Log;
use Carbon\Carbon;
use Hyperf\Crontab\Annotation\Crontab;
use Throwable;
#[Crontab(
rule: '\/10 * * * * *', // 定时任务规则
name: 'DemoScheduler', // 定时任务名称
singleton: true, // 并发执行只有一个被执行,例如: 很多个任务都是10:00AM执行时
onOneServer: true, // 多实例部署项目时,则只有一个实例会被触发
callback: 'execute', // 消费方法
memo: '测试定时任务', // 备注
enable: 'isEnable', // 是否启动
)]
class DemoScheduler extends AbstractScheduler
{
// 就算不捕获异常, 底层执行也有事件触发器触发, 会被外部监听器监听到
public function execute(): void
{
if (! $this->isRunning) {
Log::stdout()->info('DemoScheduler 消费逻辑已跳出');
return;
}
try {
// TODO your crontab task.
Log::stdout()->info(Carbon::now()->toDateTimeString());
} catch (Throwable $e) {
// TODO catch exception logic
Log::stdout()->error($e->getMessage());
} finally {
Log::stdout()->info('DemoScheduler 执行完成');
}
}
public function isEnable(): bool
{
return true;
}
}
【注意】
- 注解字段请参考:任务属性
- 注意在注解定义时,规则存在
\
符号时,需要进行转义处理,即填写*\/5 * * * * *
- 新增命令行命令控制定时任务是否执行任务。当执行:
php bin/hyperf crontab:switch stop
时,自定义进程依旧会按照执行规则执行,但是不会执行真正的业务逻辑。 你可以理解为空转
。
手动触发定时任务
当服务没有启动,想手动执行定时任务时,可以使用命令行命令执行。Hyperf v3.x
php bin/hyperf.php crontab:run