转载自:https://www.ziruchu.com/art/652
Hyperf 3 快速使用 - Hyperf 3 通过配置和注解两种方式使用定时任务
Hypref 通过 hyperf/crontab 组件提供了一个 秒级 定时任务的功能。执行定时任务会通过 Linux 中的 crontab 命令实现。
配置定时任务
第一步:安装组件包
composer require hyperf/crontab
第二步:发布配置文件
php bin/hyperf.php vendor:publish hyperf/crontab
该命令会在 config/autoload 目录下生成 crontab.php 配置文件,生成内容如下:
<?php
declare(strict_types=1);
return [
// 开启定时任务
'enable' => true,
'crontab' => [
],
];
第三步:启用任务调度器进程
在使用定时任务组件之前,需要先在 config/autoload/processes.php 内注册一下 Hyperf\Crontab\Process\CrontabDispatcherProcess 自定义进程,如下:
<?php
// config/autoload/processes.php
declare(strict_types=1);
return [
// 分发定时任务
\Hyperf\Crontab\Process\CrontabDispatcherProcess::class,
];
到这里定时任务基础配置已经完成,接下来只要编写定时任务脚本即可。
高能提示:
1、服务启动,定时任务也就启动了,但是定时任务不会立即执行;
2、服务启动后,定时任务不会立即执行,而是等到下一分才开始执行。 举例:比如定时启动时间是 23:05:05 ,那么定时任务会在 23:06:00 才正式执行。
两种方式实现定时任务
方式一:使用配置文件方式实现定时任务
第一步:定义定时任务类
<?php
namespace App\Task;
// 使用配置文件的方式执行定时任务
use Hyperf\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
class TestTask
{
protected LoggerInterface $logger;
public function __construct(LoggerFactory $loggerFactory)
{
$this->logger = $loggerFactory->get('log', 'default');
}
public function demoTask()
{
// 执行定时任务
$this->logger->info(date('Y-m-d H:id') . ' 我是王美丽呀');
}
}
第二步:配置定时任务
<?php
// config/autoload/crontab.php
declare(strict_types=1);
return [
'enable' => true,
'crontab' => [
(new \Hyperf\Crontab\Crontab())->setName('TestTask')->setRule('* * * * *')->setCallback([\App\Task\TestTask::class, 'demoTask'])->setMemo('我是备注:测试定时任务'),
],
];
第三步:启动服务
php bin/hyperf start
方式二:使用注解方式实现定时任务
第一步:定义定时任务类
<?php
namespace App\Task;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
#[Crontab(name: "DemoTask", rule: "*\/1 * * * * *", callback: "demoTask", memo: "注解定时任务说明'")]
class DemoTask
{
protected LoggerInterface $logger;
public function __construct(protected LoggerFactory $loggerFactory)
{
$this->logger = $this->loggerFactory->get('log', 'default');
}
public function demoTask()
{
$this->logger->info(date('Y-m-d H:is') . ' DemoTask 使用注解实现定时任务');
}
}
第二步:启动服务
php bin/hyperf start
了解一下定时任务的参数
public function __construct(
public ?string $rule = null,
public ?string $name = null,
public string $type = 'callback',
public ?bool $singleton = null,
public ?string $mutexPool = null,
public ?int $mutexExpires = null,
public ?bool $onOneServer = null,
public array|string|null $callback = null,
public ?string $memo = null,
public array|string|bool $enable = true
) {
}
失败任务
当定时任务执行失败时,会触发 FailToExecute 事件。因此,可以编写一个监听器类监听该事件,拿到对应的定时任务和异常。
第一步:定义异常任务类,用于模拟定时任务失败
<?php
namespace App\Task;
use _PHPStan_1292afebc\Nette\Neon\Exception;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
#[Crontab(name: "PostTask", rule: "*\/1 * * * * *", callback: "posts", memo: "post任务'")]
class PostTask
{
protected LoggerInterface $logger;
public function __construct(protected LoggerFactory $loggerFactory)
{
$this->logger = $this->loggerFactory->get('log', 'default');
}
public function posts()
{
// 此处报了异常
throw new Exception('测试定时任务');
// 正常业务逻辑
$this->logger->info('文章定时任务');
}
}
第二步:定义异常监听器
<?php
namespace App\Listener;
use Hyperf\Crontab\Event\FailToExecute;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Logger\LoggerFactory;
use Psr\Log\LoggerInterface;
#[Listener]
class FailToExecuteCrontabPostListener implements ListenerInterface
{
protected LoggerInterface $logger;
public function __construct(protected LoggerFactory $loggerFactory)
{
$this->logger = $this->loggerFactory->get('log', 'default');
}
public function listen(): array
{
return [
FailToExecute::class
];
}
public function process(object $event): void
{
$msg = '定时任务执行失败' . $event->crontab->getName() . '----' . $event->throwable->getMessage();
$this->logger->info($msg);
}
}
$event->crontab->getName() 用于获取出现异常的定时任务名称;
$event->throwable->getMessage() 用于获取定时任务出现异常消息。
第三步:测试
php bin/hyperf.php start
tail -f runtime/logs/hyperf.log
# 输出内容如下
[2023-03-18 15:33:12] log.INFO: 定时任务执行失败PostTask----测试定时任务 [] []
[2023-03-18 15:33:13] log.INFO: 定时任务执行失败PostTask----测试定时任务 [] []
调度分发策略
定时任务在设计上允许通过不同的策略来调度分发执行任务,目前仅提供了 多进程执行策略、协程执行策略 两种策略,默认为 多进程执行策略。
案例:修改为协程风格时,只需要修改config/autoload/dependencies.php
文件,配置如下:
<?php
declare(strict_types=1);
return [
'HttpServer' => Hyperf\HttpServer\Server::class,
// 修改为协程风格
\Hyperf\Crontab\Strategy\StrategyInterface::class => \Hyperf\Crontab\Strategy\CoroutineStrategy::class
];