-
Notifications
You must be signed in to change notification settings - Fork 18
components timer
- 对于计划任务, 大部分时候我们依赖系统 通过CLI方式实现, 如: linux crontab
- 而一些情况下, 当需要动态生成异步并发操作时, 我们可以使用 "动态计划任务"
- 另一些情况下, 需要并发或失败重试操作时, 我们可以使用 "静态计划任务"
- 修复框架配置_of.com.timer.mode切换启动异步任务方式
任务参数 {
#动态任务, 未指定taskObj参数
"time" : 执行时间, 五年内秒数=xx后秒执行, 其它=指定时间
"call" : 框架标准的回调 接收 "自身" 数组做系统参数,可以修改其变量,如try,达到定时执行效果
"cNum" : 并发数量, 0=不设置, n=最大值, []=指定并发ID(最小值1)
"try" : 尝试相隔秒数, 默认[], 如:[60, 100, ...]
#单子任务, taskObj返回任务对象
"call" : 框架标准的回调
#多子任务, taskObj返回 {任务标识 : 任务对象, ...}
"list" : 任务列表 {任务标识 : 框架回调结构, ...}
"cNum" : 最大并行任务数量
}
任务对象, 指定时为任务模式, 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 `根据时间查询执行范围` (`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";
}
<?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" : 框架标准的回调,
"time" : 执行时间, 时间戳,
"cNum" : 并发数量, 0=不设置, n=最大并发
"try" : 尝试相隔秒数
"this" : {
"cMd5" :o回调唯一值, 并发时存在
"cCid" :o并发ID, 从1开始, 并发时存在
"mark" :o数据回传标识, 存在时标识回传, 子任务存在
"type" : 任务类型, 1=定时器, 2=静态任务, 4=动态任务, 8=单子任务, 16=多子任务
}
}
读写数据, 仅可操作自身或未运行进程数据 null=不读数据, 仅关注运行状态使用 true=读取数据 false=清空读取, 读取数据后清空原始数据 数组=单层替换, 将数组键的值替换对应共享数据键的值
指定任务中的并发ID null=读取自身 数字=指定并发ID 数组=多个并发ID, [并发ID, ...] true=正在运行 false=包括停止
指定任务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)); //读取指定任务运行并发的存储数据
<?php
/**
type为1时 : 并发的任务 {
任务ID : {
"call" : 统一回调结构
"list" : 运行的任务列表 {
并发ID : {
"datetime" : 任务启动时间
"timestamp" : 任务启动时间戳
}
}
}
}
type为2时 : 分布定时器 {
节点名称 : {}
}
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
(
[datetime] => 2023-12-11 17:19:00
[timestamp] => 1702286340
)
)
)
)
[taskTrigger] => Array
(
[da3c61c0c3bd31efcb4c17d5b2d754d5] => Array
(
[time] => 1702286078
)
)
[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
)
)
)
*/
忽略校验的正则, true=全校验, 字符串=以"@"开头的正则忽略路径
有更新时抛出错误, ""=不抛出, 字符串=抛出的错误信息
true=有变动, false=未变动
- 文件夹 /of/accy/com/timer 下存储着不同方式的异步任务对接文件
- 目前有已封装 default swoole
- 可以通过配置文件 _of.com.timer.fork.adapter 设置, 参考配置方式
- 开发更多的存储方式, 要实现以下方法
接收参数结构 {
"asCall" : 回调方法,
"params" : [
自定义参数,
{"type" : 任务类型(同计划任务回调结构中的"type"), ...}
]
}
手册地址 http://phpof.net/
- 入门指引
-
疑难解答
- 部署时会遇到的那些常见问题
简单却容易忽视 - 框架内置有哪些管理界面
生产模式进入界面需用 __OF_DEBUG__ - 如何定制不同的架构模式
通过配置入口文件中调度方法的参数即可 - 如何面向命名空间开发
of_xx 类可以按照命名空间方式调用 - 如何设置不同的部署模式
通过_of.debug设置 开发,测试,生产 模式 - 为什么控制层类文件要返回true
这是防止非法访问的方法之一 - 为什么传到视图层的变量会被编码
这是因为 XSS 安全防范的原因 - 为什么框架没有SQL构造器
因常规方案牺牲了性能又未很好解决问题 - 如何快速开发用户及权限管理功能
单点登录(SSO)模块因此而存在 - 怎么在系统的基础上扩展底层功能
三点: 扩展开发, 预先加载, 底层钩子 - 怎么使用 Composer 依赖管理工具
框架已集成, 默认关闭状态
- 部署时会遇到的那些常见问题
- 组件使用
- 集成插件
- 扩展开发
- 开发手册