Scheduler

Scheduler即定时任务调度系统,也叫计划任务,可以通过该组件实现预设某个时间执行自定义的任务(以下简称job)。

特性

  • 可以设置job的来源信息
  • job有优先级,在可执行的任务中,任务按优先级执行
  • job的触发时间
    • 轮询,每个一个时间段执行一次
    • 定时,设定在某个时间点执行
  • 可以设置同一时刻最大执行job数设置
  • misfire机制。如果job错过了理论上应该执行的时间,并且错过的时间超过了设定的值,可以设置放弃执行还是继续执行。
  • 集群环境下,若job在一个节点上已经处于执行状态,防止该job在其他节点上执行
  • Scheduler组件的调用方式
    • 通过http请求调度
    • 通过在命令行中执行命令调度
  • job状态变迁日志的记录

开发指南

注册Scheduler组件

biz中注册SchedulerServiceProvider,示例代码如下:

  1. $biz->register(new \Codeages\Biz\Framework\Provider\SchedulerServiceProvider());
  2. // 设置`Scheduler`的参数:
  3. $biz['scheduler.options'] = array(
  4. 'max_num' => 10, // 同一时刻能执行的最大任务数,默认:10
  5. );

实现自定义Job

继承Codeages\Biz\Framework\Scheduler\AbstractJob类,并实现execute方法,示例代码如下:

  1. use Codeages\Biz\Framework\Scheduler\AbstractJob;
  2. class DeleteSessionJob extends AbstractJob
  3. {
  4. public function execute()
  5. {
  6. try {
  7. $this->beginTransication();
  8. ...
  9. $this->commit();
  10. } catch (\Exception $e) {
  11. ...
  12. $this->rollback();
  13. }
  14. }
  15. }

execute方法说明

1、由于Scheduler组件在调度任务过程中不会开启事务,如果自定义Job中需要事务支持,需要自行处理

2、对于execute函数中抛出的异常,需要捕获,不可往外抛出

3、$this->args 可以获取到job预设的参数

注册Job

构建job对象并指定执行时间,通过Scheduler:SchedulerServiceregister方法注册,示例代码如下:

  1. $job = array(
  2. 'name' => 'test', // 任务名称
  3. 'class' => 'Biz\\User\\Job\\DeleteSessionJob', // 执行的类
  4. 'expression' => '0 * * * *', // 时间表达式
  5. 'source' => 'default', // 任务来源,默认:default
  6. 'args' => array('deadline'=>1494552000), // 任务参数
  7. 'priority' => 200, // 优先级
  8. 'misfire_threshold' => 3000, // misfire超时时间
  9. 'misfire_policy' => 'missed', // misfire超时后的策略
  10. );
  11. $biz->service('Scheduler:SchedulerService')->register($job);

job的字段说明

name

类型: string 必须: 是

任务名称。

class

类型: string 必须: 是

调度的job类。

expression

类型: string or int 必须: 是

指定任务按照某个时间点、或者周期执行,是一个表达式,表达式说明如下,示例代码点击

  1. * * * * * *
  2. - - - - - -
  3. | | | | | |
  4. | | | | | + year [可选]
  5. | | | | +----- day of week (0 - 7) (Sunday=0 or 7) [必填]
  6. | | | +---------- month (1 - 12) [必填]
  7. | | +--------------- day of month (1 - 31) [必填]
  8. | +-------------------- hour (0 - 23) [必填]
  9. +------------------------- min (0 - 59) [必填]

source

类型: string 必须: 否 默认值:default

任务来源,可以通过该字段说明任务来自于哪个组件。

args

类型: array 必须: 否

该字段用于预设任务的参数,在任务实例中通过 $this->args 获取。

priority

类型: int 必须: 否 默认值:200

优先级。在可执行任务中,任务的执行顺序按优先级执行。

misfire_threshold

类型: int 必须: 否 默认值:3000

misfire的超时阀值。misfire说明:任务执行时间错过了理论上应该执行的时间。

misfire_policy

类型: string 必须: 否 默认值:missed

job执行时间错过了应该执行的时间,并超过了misfire_threshold设置的阀值后,job执行的策略。可以设置:missed或者executing

任务调度

任务调度的示例代码:

  1. $biz->service('Scheduler:SchedulerService')->execute();

EduSoho的任务调度方式

1、在crontab中加入命令行app/console util:scheduler,每分钟执行一次,配置如下:

/1 * /path/app/console util:scheduler >> /usr/local/var/log/console.log 2>&1

2、Request请求:/anon/crontab

3、所有待执行的任务,按照优先级执行,若优先级相同选择待执行时间较早的

job运行状态变迁

 任务调度  - 图1

状态说明

  • acquired: job被触发后、retry后的状态
  • ignore: 如果当前已经存在了正在运行的任务,就忽略
  • missed: 触发时间已经超过了理论执行时间,并且超过了misfireThreshold的值,job会变成missed状态
  • executing: job正在执行的状态
  • success: job执行成功的状态
  • failure: job执行失败的状态

配置方法

Linux & Mac OS

直接可以在 EduSoho 后台配置,点击重新初始化链接。

 任务调度  - 图2

如果出现以下页面,表示配置成功。

 任务调度  - 图3

Windows

Windows 操作系统,不支持后台配置,需要手动在服务器配置。

打开 控制面板 -> 管理工具 -> 任务计划程序

在右侧点击 创建任务

按照下图配置创建一个 Windows 的计划任务

 任务调度  - 图4

按照下图的配置添加一个触发器

 任务调度  - 图5

按照下图的配置添加任务触发之后的操作,建议添加 10 个一样的操作,

程序或脚本: PHP执行路径

添加参数(可选)(A): path-to-edusoho\app\console util:scheduler -v >> path-to-edusoho\app\logs\crontab.log 2>&

 任务调度  - 图6

按照下图配置条件

 任务调度  - 图7

按照下图配置其他设置

 任务调度  - 图8

配置完成之后,点击 确定 保存

保存之后,右键点击运行,进行测试

 任务调度  - 图9

运行之后,可以到 EduSoho 后台查看是否配置生效,如果 任务日志 中可以看到状态为 success 的记录,说明配置生效

 任务调度  - 图10

任务计划时间间隔问题

因为 Windows 任务计划的重复任务时间间隔,最小刻度为 5 分钟,EduSoho 推荐的最小间隔为 1 分钟,为了达到要求,你可以按照如上的方式,再重新创建四个任务,保证每一个任务的执行时间间隔为 1 分钟即可