定时任务 | Crontab
Crontab / 定时任务
项目在线上运行时,经常要定时去执行某个功能(如:定时去远程拉取一些数据、定时计算数据库里的一些数据进行汇总),这时候就需要使用定时任务来处理了。
框架提供了二种方式执行定时任务,一种是在当前启动的子进程中执行,另一种是用一个新的进程执行(命令行执行)。
当前子进程中执行
有些定时任务是拉取一些数据放在内存中,供用户请求过程中使用,这种定时任务就希望在当前进程中调用(由于框架启动服务时是多进程架构,所以定时任务只会在子进程中执行,不会在主进程中执行),该功能是通过 think-crontab 模块来完成的。
配置
定时任务的配置文件为 src/config/crontab.js
(多模块项目下配置文件为 src/common/config/crontab.js
,也支持在每个模块下配置定时任务文件 src/[module]/config/crontab.js
),配置项为一个数组。如:
module.exports = [{
interval: '10s',
immediate: true,
handle: () => {
//do something
}
}, {
cron: '0 */1 * * *',
handle: 'crontab/test',
type: 'all'
}]
每个配置项支持的参数如下:
interval
{String | Number} 执行的时间间隔 支持数字和字符串二种格式,单位是毫秒。如果是字符串,那么会用 think.ms 方法解析为数字。
调试
如果想看到定时任务是否在成功运行,可以通过 DEBUG=think-crontab npm start
启动项目查看打印的调试信息。
命令行执行
如果有些定时任务跨机房、跨机器只希望执行一次,或者定时任务比较耗时,那么可以通过命令行来执行。命令行执行需要结合系统的 crontab 任务来完成。
命令行执行直接通过自动脚本和路由地址即可,如:node production.js crontab/test
,其中 crontab/test
为路由地址,这样结合系统的 crontab 就可以定时执行了。
通过命令 crontab -e
来编辑定时任务,如:
0 */1 * * * /bin/sh (cd projectpath; node production.js crontab/test) # 1 小时执行一次
常见问题
如何限制 Action 只能定时任务调用?
默认情况下,Action 不会限制哪些情况下才允许访问,这样定时任务对应的 Action 也可以通过输入 URL 来访问。但有时候我们并不希望这样,这时候可以通过 this.isCli
判断来阻止。如:
module.exports = class extends think.Controller {
testAction() {
// 如果不是定时任务调用,则拒绝
if(!this.isCli) return this.fail(1000, 'deny'
...
}
}
定时任务执行 Action 时并不是一个正常的用户请求,而是通过模拟一个请求来完成的,模拟时会将请求类型修改为 CLI
,isCli
就是通过判断请求类型是否为 CLI
来完成的。