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、样例代码

 // 框架引入
var express = require('express');
var app = express(); var Agenda = require('agenda');
var Agendash = require('agendash');
var L = require('nirvana-logger')('agenda') // agenda初始化,并连接MongoDB
var agenda = new Agenda({db: {address: 'mongodb://localhost:32768/agenda'}}); // 定义一个测试任务
agenda.define('testJob', function (job, done) {
try {
L('hello',job.attrs.data, new Date())
done()
}catch (err) {
done(new Error(err))
}
}) // agenda框架启动
agenda.on('ready', function () {
L("====>>>agenda启动成功<<<<===")
agenda.start();
}) // Agendash UI界面
app.listen(3000);
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分钟后自动解锁任务。
  • 为避免定时任务重复执行,一般来讲定时任务微服务我们只需要部署一个实例即可。核心的业务接口处于负载均衡的考虑,可以按业务量多部署几个实例。

基于agenda的Nodejs定时任务管理框架搭建的更多相关文章

  1. (一)熟悉执行流程——基于ThinkPHP3.2的内容管理框架OneThink学习

    ThinkPHP作为国内具有代表性的PHP框架,经过多年的发展,受到越来越多公司与开发者的青睐.我也在忙里偷闲中抽出部分时间,来学习这个优秀的框架.在开始学习这个框架时,最好通过实例来学习,更容易结合 ...

  2. NodeJs之服务搭建与数据库连接

    NodeJs之服务搭建与数据库连接 一,介绍与需求分析 1.1,介绍 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻 ...

  3. 基于腾讯Centos7云服务器搭建SVN版本控制库

    基于腾讯Centos7云服务器搭建SVN版本控制库 最近在和小伙伴组队参加一个关于人工智能的比赛,无奈不知道怎么处理好每个人的代码托管问题,于是找到了晚上免费svn托管服务器的服务,但是所给的免费空间 ...

  4. 基于zookeeper的Swarm集群搭建

    简介 Swarm:docker原生的集群管理工具,将一组docker主机作为一个虚拟的docker主机来管理. 对客户端而言,Swarm集群就像是另一台普通的docker主机. Swarm集群中的每台 ...

  5. 基于Docker的TensorFlow机器学习框架搭建和实例源码解读

    概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的 ...

  6. 基于centos6.5 hbase 集群搭建

    注意本章内容是在上一篇文章“基于centos6.5 hadoop 集群搭建”基础上创建的 1.上传hbase安装包 hbase-0.96.2-hadoop2 我的目录存放在/usr/hadoop/hb ...

  7. 基于Docker部署nodejs应用

    基于Docker部署nodejs应用 背景 公司基于Vue.js的项目最近需要部署到云端,因此需要先行在公司内部Docker环境下验证相关技术,因而有本文之前提. 本文展示在Docker容器中,应用部 ...

  8. 使用基于 PHP 的开源软件 YOURLS 搭建短链接地址服务

    使用基于 PHP 的开源软件 YOURLS搭建 系统配置 php7.1+mysql5.7+nginx 下载源代码 git clone https://github.com/YOURLS/YOURLS. ...

  9. NodeJS开发环境搭建

    原创作者: zero20121222 NodeJS开发环境搭建 1.安装NodeJS 1.编译环境 源代码编译器,通常 Unix/Linux平台都自带了C++的编译器(GCC/G++).如果没有,请通 ...

随机推荐

  1. ios开发 第一天

    alloc 分配内存(类方法) init 调用构造函数 id可以替代任何数据类型(不加*号) 错误现象: 2013-06-27 21:44:21.769 FieldButtonFun[3465:113 ...

  2. excel去除空格

    =SUBSTITUTE(Sheet1!A1," ","") 在sheet2中输入上述公式,然后再通过拖拽复制公式,即可以很快的将sheet1中的数据全部处理.

  3. python_19_异常处理

    什么是异常处理? -- 对于用户输入,不想让用户看见出错信息,对异常进行处理 异常处理的框架是什么? try: 可能出错的程序1 可能出错的程序2        #程序1出错了,不在执行程序2 exc ...

  4. requests_模拟登录知乎

    如何登录知乎? 首先要分析,进行知乎验证的时候,知乎服务器需要我们提交什么数据,提交的地址.先进行几次登录尝试,通过浏览器中network中查看数据流得知,模拟登录知乎需要提供5个数据,分别是_xsr ...

  5. junit4X系列--Statement

    原文出处:http://www.blogjava.net/DLevin/archive/2012/05/11/377954.html.感谢作者的无私分享. 初次用文字的方式记录读源码的过程,不知道怎么 ...

  6. JavaWeb项目架构之Redis分布式日志队列

    架构.分布式.日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Redis做消息队列罢了. 前言 为什么需要消息队列? 当系统中出现"生产"和" ...

  7. SQL模板资源管理器,你用了吗?

    SQL Server Management Studio 有个模板资源管理器,不知你用过没有?使用模板创建脚本.自定义模板等功能能大大提高你的工作效率,如果没有尝试过,赶紧去试试吧.很多时候,我们习惯 ...

  8. android 中的ExpandableListView取消一级图标

    mainlistview = (ExpandableListView) view.findViewById(R.id.listview_myteacher); mainlistview.setGrou ...

  9. weex 启动 android 模拟器(mac环境)

    一.android studio和android sdk下载 1.android studio下载并安装https://developer.android.com/studio/index.html ...

  10. HTML——filedset和legend标签

    1.<filedset>定义围绕表单中元素的边框. 2.legend 元素表示作为 legend 元素的父元素的 fieldset 元素的其余内容的标题(caption). 使用案例: & ...