hf3.0 转载自如出 定时任务用法

转载自: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
];
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容