定时任务(Schedule)

例:我们在 app/schedule 目录下创建一个 pvSchedule.ts 文件

import {AbstractSchedule}  from '@umajs/plugin-schedule'

export default class PvSchedule extends AbstractSchedule {
    constructor(app){
        super(app)
        this.scheduleInfo = {
           // rule:'0 0/1 * * * ?', // 每1分鐘更新一次
           // name:'PV', // 定时任务名称
            // switch:true, // 开启定时任务
        }
    }

    /**
     * 业务实现
     */
    public task() {
       // todo task
    }

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

配置

1,在 config/plugin.config.ts 开启

    'schedule': {
        enable: true,
    }

1
2
3
4

2,新建 schedule.config.ts,在其中填入配置项

export default [
    {
        task: PvSchedule, // 定时任务类
        auto: true, // true 代表自动执行,false代表手动执行
        mark:"pv" // 任务标记
    },
    {
        ...
    }]

1
2
3
4
5
6
7
8
9
10

3,controller 初始化定时任务参数配置

export default class PvSchedule extends AbstractSchedule {
    constructor(app){
        super(app)
        this.scheduleInfo = {
           rule:'0 0/1 * * * ?', // 每1分鐘更新一次
           name:'PV', // 定时任务名称
            switch:true, // true:开启定时任务; false:关闭定时任务
            ...app
        }
    }

    /**
     * 业务实现
     */
    public task() {
       // todo task
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

任务

  • 手动启动定时任务
import { umaTask } from '@umajs/plugin-schedule'

umaTask('pv').start()
1
2
3
  • 自动启动
auto: true
1
  • 手动关闭定时任务
umaTask('pv').cancel()
1

定时方式

  • Cron 风格定时器 (建议使用 Cron 风格,避免服务器时间不一致)
*  *  *  *  *  *
┬ ┬ ┬ ┬ ┬ ┬
│ │ │ │ │  |
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
│ │ │ │ └───── month (1 - 12)
│ │ │ └────────── day of month (1 - 31)
│ │ └─────────────── hour (0 - 23)
│ └──────────────────── minute (0 - 59)
└───────────────────────── second (0 - 59, OPTIONAL)

6个占位符从左到右分别代表:秒、分、时、日、月、周几

1
2
3
4
5
6
7
8
9
10
11
12
  • interval 风格定时器,更多配置参考 node-schedule
import * as schedule from 'node-schedule';
let rule = new schedule.RecurrenceRule();
rule.second =[0,1,2,3......59] 每秒执行
rule.second =0 每分钟0秒执行
rule.minute =0 每小时30分执行

this.scheduleInfo = {
    rule, // 每1分鐘更新一次
}

1
2
3
4
5
6
7
8
9
10

集群/分布式部署 执行定时任务

  • 插件包含在分布式部署下,需要保证同一个定时任务只能运行一次,所以需要用事物锁来控制;
  • 插件采用的是分布式事务锁方案,支持单台 redis 和多台 redis 方案,基于 ioredis 实现
import * as RedLock  from 'redlock'
import * as Redis from 'ioredis';

const client1 = new Redis({
    host: 'redis1.example.com',
    port: 6379,
    family: 4,
    db: 0,
    pass: 'xxx',
    password: 'xxx',
});
const client2 = new Redis({
    host: 'redis2.example.com',
    port: 6378,
    family: 4,
    db: 0,
    pass: 'xxx',
    password: 'xxx',
});

this.scheduleInfo= {
    rule: '0 0/1 * * * ?', // 每1分鐘更新一次
    name: 'pv', // 任务名称
    switch: true, // 定时任务开启
    redLock:new RedLock([client1,client2]), // 采用redis锁 
    redLockTKL:10000 ,//单位毫秒,锁的生存时间,在该时间内,若锁未释放,强行释放 避免死锁情况
    sleep:1000  //单位毫秒,执行任务后主动释放锁的时间
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28