Skip to content

components timer

tolizhan edited this page May 1, 2025 · 16 revisions

计划任务

使用说明

  1. 对于计划任务, 大部分时候我们依赖系统 通过CLI方式实现, 如: linux crontab
  2. 而一些情况下, 当需要动态生成异步并发操作时, 我们可以使用 "动态计划任务"
  3. 另一些情况下, 需要并发或失败重试操作时, 我们可以使用 "静态计划任务"
  4. 修复框架配置_of.com.timer.mode切换启动异步任务方式

动态计划任务 在代码执行时动态调用

of_base_com_timer::task($params, &$taskObj = null)

paramsarray
任务参数  {
    #动态任务, 未指定taskObj参数
    "time" : 执行时间, 五年内秒数=xx后秒执行, 其它=指定时间
    "call" : 框架标准的回调 接收 "自身" 数组做系统参数,可以修改其变量,如try,达到定时执行效果 
    "cNum" : 并发数量, 0=不设置, n=最大值, []=指定并发ID(最小值1)
    "try"  : 尝试相隔秒数, 默认[], 如:[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 `根据时间查询执行范围` (`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 : {
                  "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                   )           )   )  */

of_base_com_timer::renew($preg = true, $eTip = '') 判断已加载文件是否有更新

pregtrue string
忽略校验的正则, true=全校验, 字符串=以"@"开头的正则忽略路径
eTipstring
有更新时抛出错误, ""=不抛出, 字符串=抛出的错误信息
返回
true=有变动, false=未变动

二次开发

  1. 文件夹 /of/accy/com/timer 下存储着不同方式的异步任务对接文件
  2. 目前有已封装 default swoole
  3. 可以通过配置文件 _of.com.timer.fork.adapter 设置, 参考配置方式
  4. 开发更多的存储方式, 要实现以下方法

public static function fork($params) 启动异步任务

paramsarray
接收参数结构 {
    "asCall" : 回调方法,
    "params" : [
        自定义参数,
        {"type" : 任务类型(同计划任务回调结构中的"type"), ...}
    ]
}
Clone this wiki locally