使用说明
- 对于计划任务, 大部分时候我们依赖系统 通过CLI方式实现, 如: linux crontab
- 而一些情况下, 当需要动态生成异步并发操作时, 我们可以使用 "动态计划任务"
- 另一些情况下, 需要并发或失败重试操作时, 我们可以使用 "静态计划任务"
- 修复框架配置_of.com.timer.mode切换启动异步任务方式
动态计划任务 在代码执行时动态调用
of_base_com_timer::task($params, &$taskObj = null)
paramsarray
任务参数 {
#动态任务, 未指定taskObj参数
"time" : 执行时间, 五年内秒数=xx后秒执行, 其它=指定时间
"call" : 框架标准的回调 接收 "自身" 数组做系统参数,可以修改其变量,如try,达到定时执行效果
"cNum" : 并发数量, 0=不设置, n=最大值, []=指定并发ID(最小值1)
"try" : 尝试相隔秒数, "call"返回false时会隔首个数字秒后重试, 默认[], 如:[60, 100, ...]
#单子任务, taskObj返回任务对象
"call" : 框架标准的回调
#多子任务, taskObj返回 {任务标识 : 任务对象, ...}
"list" : 任务列表 {任务标识 : 框架回调结构, ...}
"cNum" : 最大并行任务数量
}
&taskObj
任务对象, 指定时为任务模式, swoole环境下性能更高
<?php
/**
* 本函数内部会自动运行定时器, 如果定时器进程经常被系统杀死,
* 可以在常用页面使用of_base_com_timer::timer()手动运行
* _of.com.timer 为计划任务的配置
* 如果 _of.com.timer.task.adapter 为 mysql, 需要下面的语句创建表, 也可以在 time 上做分区
* CREATE TABLE `_of_com_timer` (
* `hash` char(50) NOT NULL DEFAULT '' COMMENT '唯一标识符(十六进制时间戳+回调序列化的md5)',
* `time` int(11) NOT NULL DEFAULT '0' COMMENT '执行时间戳',
* `task` mediumtext NOT NULL COMMENT '存储调用数据{"call":回调结构,"try":尝试次数}',
* PRIMARY KEY (`hash`),
* KEY `idx_time` (`time`) USING BTREE
* ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='框架计划任务存储列表';
*/
of_base_com_timer::task(array(
'time' => 600, //十分钟后触发回调
'call' => array(
'asCall' => 'demo_index::index', //回调方法,返回 false 认为失败
'params' => array('自定义参数1') //自定义参数,
),
'cNum' => 3, //有且仅有3个并发一起执行
'try' => array(
100, //失败后100s重试
90 //再失败90s重试
)
));
<?php
/**
* 获取回调任务返回信息
*/
of_base_com_timer::task(array(
'call' => array(
'asCall' => 'demo_index::index', //回调方法,会回传返回值
'params' => array('自定义参数1') //自定义参数,
),
), $taskObj);
/**
* 描述 : 获取任务结果
* 参数 :
* wait : 最大尝试时间(秒), 默认86400(24小时), 0=尝试一次
* 返回 :
* false=任务运行中, true=任务中途退出(exit throw kill), array=任务正常返回 {
* "result" : 任务返回的结果
* }
*/
var_dump($taskObj->result());
<?php
/**
* 获取回调任务返回信息
*/
of_base_com_timer::task(array(
'list' => array(
'a' => array(
'asCall' => 'demo_index::index',
'params' => array('自定义参数1')
),
'b' => array(
'asCall' => 'demo_index::index',
'params' => array('自定义参数1')
)
),
'cNum' => 1 //最大同时执行list中的一个任务
), $list);
print_r($list); //{"a" : obj, "b" : obj}
echo time(), "\n";
foreach ($list as $k => &$v) {
var_dump($v->result());
echo time(), "\n";
}
静态计划任务 写在配置文件 "_of.com.timer.cron.path" 中指定的路径中
<?php
/**
* OF_URL/index.php?c=of_base_com_timer 激活计划任务
* call 与 try 参考 of_base_com_timer::task 动态计划任务
* time 参数 符合 linux crontab 语法定义, "* * * * *" 分 时 日 月 星期(0-6 0为星期日)
* "* * * * *" 每1分钟执行一次
* "3,15 * * * *" 每小时的第3和第15分钟执行
* "3,15 8-11 * * *" 上午8点到11点的第3和第15分钟执行
* "3,15 8-11 */2 * *" 每隔两天的上午8点到11点的第3和第15分钟执行
* "3,15 8-11 * * 1" 每个星期一的上午8点到11点的第3和第15分钟执行
* "30 21 * * *" 每晚的21:30执行
* "45 4 1,10,22 * *" 每月1、10、22日的4:45执行
* "45 4 -1 * *" 负数为倒数, 每月最后一天的4:45执行
* "0 2 * * 6,0" 每周六、周日的2:00执行
* "* 2 * * 6,0" 每周六、周日的2:00-2:59每分钟执行一次
* "0 20-7/2 * * *" 晚上8点到早上7点之间, 每隔2小时执行
*/
return array(
array( //可以定义键值
'time' => '*/2 */5,1,*,14-30/3 * * 1', //符合 linux crontab 语法定义
'call' => array(
'asCall' => 'demo_ofControllers::cc', //回调方法,返回 false 认为失败
'params' => array('自定义参数1') //自定义参数,
),
'cNum' => 3, //有且仅有3个并发一起执行
'try' => array(60, 120, 300)
)
);
计划任务回调 动态与静态计划任务回调结构统一
call方法接收的触发参数结构
{
"call" : 框架标准的回调,
"time" : 执行时间, 时间戳,
"cNum" : 并发数量, 0=不设置, n=最大并发
"try" : 尝试相隔秒数
"this" : {
"cMd5" :o回调唯一值, 并发时存在
"cCid" :o并发ID, 从1开始, 并发时存在
"mark" :o数据回传标识, 存在时标识回传, 子任务存在
"type" : 任务类型, 1=定时器, 2=静态任务, 4=动态任务, 8=单子任务, 16=多子任务
}
}
of_base_com_timer::data($data = true, $cIds = null, $call = null) 为并发提供共享数据
datanull bool array
读写数据, 仅可操作自身或未运行进程数据
null=不读数据, 仅关注运行状态使用
true=读取数据
false=清空读取, 读取数据后清空原始数据
数组=单层替换, 将数组键的值替换对应共享数据键的值
cIdsnull int bool array
指定任务中的并发ID
null=读取自身
数字=指定并发ID
数组=多个并发ID, [并发ID, ...]
true=正在运行
false=包括停止
callnull string array
指定任务ID
null=读取自身
'/'开头字符串=指定任务ID
符合框架回调结构=指定任务的回调
返回
{
"info" : {
并发ID, 从小到大排序 : {
"isRun" : 是否运行, true=运行, false=停止
"sort" : 在返回列表中的位置, 从0开始
"data" : 并发所存修改前的数据
}, ...
}
//在并发回调方法中调用 print_r(of_base_com_timer::data()); //读取当前任务当前并发的存储数据 print_r(of_base_com_timer::data(null, true)); //读取当前任务运行并发的存储数据 print_r(of_base_com_timer::data(null, false)); //读取当前任务所有并发的存储数据 //假设通过 of_base_com_timer::info(1) 获取的任务ID为 $id print_r(of_base_com_timer::data(null, true, '/' . $id)); //读取指定任务运行并发的存储数据
of_base_com_timer::info($type) 获取当期运行的信息
typeint
读取类型(可叠加), 1=并发的任务, 2=分布定时器, 4=当前任务
<?php
/**
* type为1时 : 并发的任务 {
* 任务ID : {
* "call" : 统一回调结构
* "list" : 运行的任务列表 {
* 并发ID : {
* "time" : 任务启动时间戳
* }
* }
* }
* }
* type为2时 : 分布定时器 {
* 节点名称 : {
* "nodeAddr" : 节点IP地址
* "nodeTime" : 启动时间, 若出现与部署时间差距较大, 可能是当前主机的系统异常重启
* "nodeSort" : 在返回列表中的位置, 从0开始
* "sortTime" : 排序时间, 每次nodeSort变更时更新, 若出现与nodeTime差距较大, 可能是其它节点或"_ofSelf"服务异常
* "prevSort" : 列表位置变更前的位置, 未变更为-1, 若出现比nodeSort小的情况, 可能是_ofSelf的K-V被第三方改写的问题
* }
* }
* type为4时 : 获取当前任务, null=当前不在异步中, array={
* "task" : 同task任务参数
* "cArg" : 并发参数, 数组=启动并发 {
* "cMd5" :o回调唯一值, 并发时存在
* "cCid" :o并发ID, 从1开始, 并发时存在
* "mark" :o数据回传标识, 存在时标识回传, 子任务存在
* "type" : 任务类型, 1=定时器, 2=静态任务, 4=动态任务, 8=单子任务, 16=多子任务
* }
* }
* type其它时 : 如1|2|4为7时 {
* "concurrent" : type为1的结构,
* "taskTrigger" : type为2的结构,
* "nowTaskInfo" : type为4的结构
* }
*/
print_r(of_base_com_timer::info(7));
/**
* 输出如下 :
* Array
* (
* [concurrent] => Array
* (
* [305e58827000c31d7249a297790aa22f] => Array
* (
* [call] => Array
* (
* [0] => ctrl_index
* [1] => asyn
* )
* [list] => Array
* (
* [1] => Array
* (
* [time] => 1702286340
* )
* )
* )
* )
* [taskTrigger] => Array
* (
* [da3c61c0c3bd31efcb4c17d5b2d754d5] => Array
* (
* [nodeAddr] => 127.0.0.1
* [nodeTime] => 1702286078
* [nodeSort] => 0
* [sortTime] => 1702286078
* [prevSort] => -1
* )
* )
* [nowTaskInfo] => Array
* (
* [call] => Array
* (
* [time] => 1702286340
* [call] => Array
* (
* [0] => ctrl_index
* [1] => asyn
* )
* [cNum] => Array
* (
* [0] => 1
* )
* [try] => Array
* (
* [0] => 60
* [1] => 120
* [2] => 300
* )
* )
* [cArg] => Array
* (
* [cMd5] => 305e58827000c31d7249a297790aa22f
* [cCid] => 1
* [type] => 2
* )
* )
* )
*/
of_base_com_timer::renew($preg = true, $eTip = '') 判断已加载文件是否有更新
pregtrue string
忽略校验的正则, true=全校验, 字符串=以"@"开头的正则忽略路径
eTipstring
有更新时抛出错误, ""=不抛出, 字符串=抛出的错误信息
返回
true=有变动, false=未变动
二次开发
- 文件夹 /of/accy/com/timer 下存储着不同方式的异步任务对接文件
- 目前有已封装 default swoole
- 可以通过配置文件 _of.com.timer.fork.adapter 设置, 参考配置方式
- 开发更多的存储方式, 要实现以下方法
public static function fork($params)启动异步任务
paramsarray
接收参数结构 {
"asCall" : 回调方法,
"params" : [
自定义参数,
{"type" : 任务类型(同计划任务回调结构中的"type"), ...}
]
}