• 基于agenda的Nodejs定时任务管理框架搭建


    0、背景

      在大型项目中,定时任务的应用场景越来越广。一般来说,按照微服务的思想,我们会将定时任务单独部署一套服务,核心的业务接口独立到另一个服务中,从而降低相互之间的耦合程度。在需要使用定时任务时,只需要由定时任务微服务定时向核心业务服务发起异步接口调用。

      基于NodeJS来搭建这样一套定时任务的话,我们可以使用现有比较成熟的第三方框架来快速搭建,开发人员只需要关注定时任务的实现逻辑即可。

    1、agenda

      在github搜索nodejs schedule的话会有很多类库,比如node-schedule,agenda,node-cron等。之所以选择agenda的话主要由两个原因:1、agenda接口简单,还可使用人类可读的cron表达式;2、agenda提供了完整的Restful API接口,以及可统计查看操作的UI界面。

      这样的话,我们只要在代码中提前定义好定时任务处理逻辑,然后就可以在界面在新增或者移除定时任务安排,而无需重新上线。

      下面我们就开始从头搭建基于agenda的定时任务。

    2、基础环境准备

    • MongoDB:agenda需要使用MongoDB来存储定时任务数据。建议大家使用docker进行一建安装,操作简单,删除也方便。只需要docker中搜索mongo,选择安装默认推荐的官方版即可。
    • agenda:定时任务管理框架,文档参考:https://github.com/agenda/agenda
    • agendash:基于agenda的UI管理界面,文档参考:https://github.com/agenda/agendash
    • express:用于配合agendash启动WEB服务
    • nirvana-logger:非必选,nodejs日志输出框架,文档参考:https://www.npmjs.com/package/nirvana-logger

    3、样例代码

     1 // 框架引入
     2 var express = require('express');
     3 var app = express();
     4 
     5 var Agenda = require('agenda');
     6 var Agendash = require('agendash');
     7 var L = require('nirvana-logger')('agenda')
     8 
     9 // agenda初始化,并连接MongoDB
    10 var agenda = new Agenda({db: {address: 'mongodb://localhost:32768/agenda'}});
    11 
    12 // 定义一个测试任务
    13 agenda.define('testJob', function (job, done) {
    14   try {
    15     L('hello',job.attrs.data, new Date())
    16     done()
    17   }catch (err) {
    18     done(new Error(err))
    19   }
    20 })
    21 
    22 // agenda框架启动
    23 agenda.on('ready', function () {
    24   L("====>>>agenda启动成功<<<<===")
    25   agenda.start();
    26 })
    27 
    28 // Agendash UI界面
    29 app.listen(3000);
    30 app.use('/dash', Agendash(agenda));

     

    13行:定义一个任务,名称为testJob,后续我们可以通过该名字安排定时任务。第二个参数是一个函数,用于处理我们的业务逻辑,需要注意的是,我们需要在任务完成之后主动调用done方法,这样agenda才会将任务标记为完成。

    17行:如果任务执行过程中出现异常(比如网络请求异常)时,需要向done传入一个error对象,agenda会将此任务标记为fail状态。

    23行:在agenda连接MongoDB成功后,会触发ready的钩子,我们才能在这里开始安排定时任务,并且让agenda开始执行定时任务扫描。

    29行:在3000端口启动express,同时使用agendash框架启动agenda的WEB管理界面。

    执行node命令启动该js文件,如果能在命令行看到“agenda启动成功”则表示agenda连接数据库成功并且成功启动。

    其实细心的同学可以,我们在上面的代码中只是定义了任务,但是并没有对进行对任务进行定时运行。

    所以接下来我们将演示如何在WEB界面上对定时任务进进行查询,新增以及删除的操作。

    现在我们可以打开:http://localhost:3000/dash/# 来查看web界面。

    4、定时任务界面管理

    打开agendash的默认界面是这样

     

    从界面上也可以看出,我们现在的确并未启动任何定时任务。

    4.1 新增定时任务

    点击【Schedule job】,在后面弹出create job界面:

     Job name:我们需要使用的任务名称,即我们在程序中提前设置好的任务,比如刚才定义的testJob

    Schedule:安排定时任务,这里我们输入希望定时任务执行的时间点,比如5 minutes。这里时间的支持具体请参考:https://github.com/agenda/human-interval

    Repeat every:循环执行定时任务,这里输入循环间隔时间。比如5 seconds。这里需要注意的是schedule安排的任务只会执行一次,repeat任务会一直循环执行。所以这二者一般只需要按需求填一个即可。

    Job data:向定时任务传入的额外数据,我们可以在任务执行时通过job.attr.data获取到这些参数。

    点击保存后,我们的定时任务就开始运行,可以看到控制台开始循环执行打印日志:

    同时WEB界面数据将会更新,我们也能看到定时任务的运行状态:

    schedule安排一次性的定时任务也是类似的操作,大家可以自己尝试。

    值得注意的是,我们定义的任务,是可以被重复执行定时任务。

    4.2 移除定时任务

    点击某一个定时任务,就能查看到任务的详细信息以及相关操作。

    点击右上角的【delete selected】即可删除该定时任务。 

    5、几个注意点

    • 定时任务的时间除了使用cron表达式以外,还只能简单的英文表达,具体要参考https://github.com/agenda/human-interval
    • 定时任务在执行过程中会将设置为锁定状态,任务执行完成以后再将任务锁定状态解除。所以如果任务在执行过程中,程序退出的话,那么就会导致任务一直处于锁定状态,agenda默认10分钟后自动解锁任务。
    • 为避免定时任务重复执行,一般来讲定时任务微服务我们只需要部署一个实例即可。核心的业务接口处于负载均衡的考虑,可以按业务量多部署几个实例。
  • 相关阅读:
    【ST】lab01——Junit and Eclemma
    【SPM】hw1——个人房间装修
    【ST】hw2——find the error in the follow case
    【ST】Describe an error from my past projects
    ST homework4 --- 图覆盖
    ST lab1——Junit和覆盖测试的初探
    ST work12——failure,fault,error
    ST work1——印象最深的一个bug DJI 激活时报 SDK_ACTIVE_SDK_VERSION_ERROR
    C# note 06——delegate 和 event
    C# note 05——异常处理
  • 原文地址:https://www.cnblogs.com/souvenir/p/8480182.html
Copyright © 2020-2023  润新知