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. Python调用外部程序——os.system()和subprocess.call

    通过os.system函数调用其他程序 预备知识:cmd中打开和关闭程序 cmd中打开程序 a.打开系统自带程序 系统自带的程序的路径一般都已加入环境变量之中,只需在cmd窗口中直接输入程序名称即可. ...

  2. Django将request对象传入模板配置

    对于很多时候,需要从模板中获取很请求中很多内容,比如当前请求的url,当前的session变量中的某个值,这时候我们可以通过配置可将request对象传递进模板. django1.10版本: sett ...

  3. 使用SQL 提示优化sql

    use index 在查询语句中表名的后面,添加use index来提供希望mysql去参考的索引列表,就可以让mysql不再考虑其他可用的索引 explain select * from renta ...

  4. Django_404_403_500页面处理

    需求: 进入上线环境,用户并没有权力知道出错信息,那我们需要对不同的出错信息返回不同页面提示,提升用户的体验 问题原因: 生产环境下,用户输入的url地址不正确,没有对应的view去处理这个url请求 ...

  5. python_6_字符串

    什么是字符串? --一般用户输入数据和一堆有意义或者没有意义的文字符号组合 对字符串有哪些操作? --字符串本身不能修改,可以切片,可以读取 -- .capitalize()              ...

  6. python_计算1+……+100中偶数和

    如何计算1+--+100中偶数和? 1. 把奇数去掉,通过if,判断累加数除以2的余数,是否为1,判断是否是奇数 2. 通过continue 跳过对奇数的累加 #!/usr/bin/python3 d ...

  7. Linux指令--ln

    ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在 ...

  8. mysql 列转行,合并字段

    数据表: 列转行:利用max(case when then) max---聚合函数 取最大值 (case course when '语文' then score else 0 end) ---判断   ...

  9. CSS常用字体名称

    CSS样式中常用的字体名称   css中引入字体: @font-face { font-family: "AncientWar"; src: url('style/css/font ...

  10. DNS服务器解析域名的过程

    最近在读许令波老师的<深入分析Java Web技术内幕>,算是对DNS服务器域名解析有个大体的理解,以下的内容来自个人对书中内容的整理 1.什么是域名解析? 当我们在浏览器的地址栏输入一个 ...