计划任务包括两种应用模式: 精确延时任务 、轮询计划任务
精确延时任务精确延时任务一般是在某个具体的时间点,触发任务。比如有这样的需求,拼团活动创建,30分钟内,要不成团,要不关闭。整点秒杀活动在13:35:00这个时间正点开始。这样的需求,使用精确延时任务可以实现相关功能。
插件开发中精确延时任务的开发步骤

1、精确延时任务的使用简单,您可以在任意需要调用精确延时的地方启动任务计划,调用方法如下
OrderClose::invoke([, secs:20) ;
通过上面的方法调用,就启动了一个20秒后,会自动执行回调的精确延时任务OrderClose是继承自BaseJob的一个子类,BaseJob是继承自Dispatch的一个子类,invoke是一个静态方法,用于调用精确延时任务的方法。Invoke的第一个参数是 action, 表示一个方法名,默认不填,就是 doJob方法回调,也可以传入自己定义的回调函数方法名称 ,第二个参数secs 表示延时的秒数,如果是更长时间,某年某月某日后的某个时间点,自己计算赋值
class Dispatch{
/
加入队列
@param $action
@param array $data
@param string|null $queue_name
@return mixed
/
public static function invoke($action, array $data = [], int $secs = 0, string $queue_name = null, bool $is_async = true)
{
$class = get_called_class();//调用主调类
if ($is_async) {
$queue = Queue::instance()->job($class)->secs($secs);
if (is_array($action)) {
$queue->data(...$action);
} else if (is_string($action)) {
$queue->method($action)->data(...$data);
}
if ($queue_name) {
$queue->setQueueName($queue_name);
}
return $queue->push();
} else {
$class_name = '\\' . $class;
$res = new $class_name();
if (is_array($action)) {
return $res->doJob(...$action);
} else {
return $res->$action(...$data);
}
}
}}
1、计划任务的精确时间延时点到达后,系统自动回调,然后在OrderClose类中相应的doJob函数中,编写具体的业务逻辑实现代码
/
队列异步调用定时任务
/
class OrderClose extends BaseJob{
public function doJob()
{
Log::write('订单关闭计划任务'.date('Y-m-d h:i:s'));
return true;
}}
轮询计划任务
轮询计划任务是按照固定的时间间隔触发,在每个触发的时间间隔,开发者在对应的回调函数(异步函数)中,对相关的业务逻辑进行处理,通常时间间隔可以设置为1分钟。例如有这样的应用场景,检测站点是否到期,程序处理自动关闭操作。又如订单创建后,30分钟内没有人付款,订单自动关闭。一般这样的业务逻辑,对时间的要求不是非常精准的。就可以在轮询中进行处理。
插件开发中轮训计划任务的开发步骤
1、在插件的目录addon\hello_world\app\dict\schedule.php 文件中, 编写轮训计划任务的相关数据描述定义
return [
[
'key' => 'order_close',
'name' => '未支付订单自动关闭',
'time' => [
'type' => 'min',
],
'class' => '',
'function' => ''
]];
'key' => 'order_close' order_close 对应 OrderClose两个单词,目前在niucloud-admin框架内部系统加载的时候,如果没有填写class 参数,会自动寻找 app\job\schedule目录下对应的文件名来装载类'name' => '未支付订单自动关闭' 计划任务的名称'time' => [ 'type' => 'min', ] 计划任务的执行时间,一般写min 表示每分钟间隔会调用 class 下的 function 函数一次'class' => '' 这个表示任务时间间隔时,回调的处理类,要带命名空间,对于插件开发,这里必须填写完整的类路径 如 addon\hello_world\app\job\schedule\OrderClose ( 对于插件中开发计划任务,目前框架没有优化处理自动找寻类, ),注意!
这里的schedule目录不是固定的,可以定义任意路径'function' => '' 计划任务回调执行的函数,默认为空,则函数为 doJob 。 开发人员可以定义人员的函数名称
2. 计划任务时间触发,自动回调,在相应的函数中,编写具体的业务逻辑实现代码
/
队列异步调用定时任务
/
class OrderClose extends BaseJob{
public function doJob()
{
Log::write('订单关闭计划任务'.date('Y-m-d h:i:s'));
return true;
}}