在 node 的一些小型项目中我们可以使用 Agenda 模块来完成定时任务。从个人角度上来说并不建议使用 node完成定时任务,毕竟 node 擅长的是 IO 而不是 CPU 计算。
与其他定时任务比较, Agenda 有着最小的开销以及持久化的优势。即便程序重启了,也不会丢失现有任务。
Agenda 简介
Agenda 是基于 node 的一个轻量级任务调度类库,它的优势在于轻量级、持久化、使用简单。
1)持久化
Agenda 引入mongodb从而实现持久化 。Agenda 将所有的任务(job)存储到mongodb中,对于使用mongodb做数据库的项目有天然优势。
2)结构
在 Agenda 启动时会将预定义好的 processors 遍历一遍,从mongodb中查询出符合条件 job(这里的 job 可能不止一条)。对于遍历查询出来的job:如果时间已到或者已经是过去时间,那么立即执行;如果时间还未到,那么就延迟执行。
3)API
Agenda 之所以受欢迎,与其简单灵活的 API 是分不开的。
Agenda 使用步骤
使用简单是 Agenda 一大优势,只需短短的几行代码便可使任务按照既定的计划运行。
1、实例化
Agenda 实例的创建,在创建过程中主要做了:
连接mongo数据库
初始化内部变量
2、定义 processor
processor 指的是:在 job 按照需求到达指定的执行时间点时,需要执行的操作,也就是实际的业务逻辑。这部分逻辑是保存在内存中的,一但程序挂掉processor 也会丢失。
所以最好在程序启动的时候定义 processor,这样下次重启程序,processor 会被重新保存到内存当中。
定义一个定时更新用户信息的 job,define 方法有三个参数:
1)name
表示任务的名称,任务不可以与已有任务重名,否则会覆盖已有任务
2)options
表示设置任务属性:
concurrency: 表示并发数,可运行任务的最大数量
lockLimit:任务被锁住的最大数量(Agenda 在运行一个任务时,会将当前任务锁住,以以防止重复执行任务)
lockLifetime:任务被锁住的时间,如果 done() 调用,任务将自动解锁。
priority:任务执行的优先级(分为lowest、low、normal、high、highest、number)
以上代码就对其并发量 concurrency 做了限制,设置同时可运行任务数为5。
3)processor
第三个参数(processor)即回调函数中实现我们的处理逻辑。回调函数有两个参数,job 表示当前执行的任务信息,而回调函数的第二个参数 done 是可选的:
done 的使用还是需要根据实际情况而定。例如这段代码中,我们省略了 options 参数,这时 Agenda 内部就会使用默认参数。我们省略了回调函数中的 done,这就意味着我们在回调函数中的逻辑可以使用异步调用。
3、创建定义任务
处理逻辑定义完成之后,我们需要进行定义任务,规定任务的执行时间、周期等。对于任务的定义,Agenda 为我们准备了以下4个方法:
every指定的任务每隔一个固定的时间执行一次
schedule计划任务,此方法跟 Linux 的计划任务几乎一致
now立即执行任务
create创建一个任务
1)every
根据业务的需求,如果某些任务需要在项目整个生命周期一致运行的的时候,我们可以使用 every 方法。例如,在一定间隔时间抓取天气情况。
2)schedule
定时周期性任务很常见,主要作用是将任务计划在指定时间运行一次:
3)now
立即执行任务:
4、思考与探索
每个码农可能都会存在一种工匠精神:虽然读懂 API,可以满足一般需求和正常的使用,但总会觉得有点不够。光会使用是不够的,我们需要梳理 Agenda 与项目之间的关系。
如上图中:在原始架构中,每个项目都会启用一个 Agenda 实例。但我们可以启用一个 Agenda 实例来处理所有项目中的任务调度,不仅可以节省 CPU 资源,还可以将 Agenda 服务化(将 Agenda 从业务中剥离,只去做纯粹的任务调度)。
按照以上想法,我们将 Agenda 的任务调度操作统一交由一个进程处理(且称之为调度进程),各个使用者只需要通过 API 对调度进程中存储的任务进行操作即可,而不必关心调度进程内部是怎么实现的。这和当前非常流行的微服务有点相似。
如何动态添加任务?我们就需要用到上一节中所遗留的方法:
4)create
在这里我们手动创建了任务,设置每隔10分调用一次任务,并保存到 mongodb 中。这样一来,我们就可以通过 API 来操作任务(添加、删除等)。
风险和收益往往是并存的。享受统一调度带来的方便之时,我们也随之承受着可能的风险:如果我们的调度进程 crash 之后,会导致所有使用者的任务都不能正常有效的执行。
我们需要将此服务做到:简单、独立、健壮,以此来满足企业级别的需求。
总结
以上就是笔者对 Agenda 介绍与探索。很多时候,我们应该避免重复造轮,才可以在满足需求的情况下,提升程序性能与工作效率。
本文作者:孙卫峰(点融黑帮), 现就职于点融 Clients 部门,爱折腾,爱思考,爱老婆的程序猿一枚。