摘要:通過實(shí)例的方法,就可以綁定事件和處理函數(shù),第一個(gè)參數(shù)是事件名稱,第二個(gè)就是處理事件的回調(diào)函數(shù)因?yàn)樘幚硎沁^程是異步的,所以結(jié)束之后要調(diào)用。
在軟件系統(tǒng)的運(yùn)維中,總有一些事件,需要在特定的時(shí)間來觸發(fā)執(zhí)行,這個(gè)時(shí)候,我們需要用到定時(shí)任務(wù)。
agenda是nodejs實(shí)現(xiàn)的基于mongodb數(shù)據(jù)庫的分布式定時(shí)任務(wù)管理系統(tǒng)。agendash則為agenda提供了一個(gè)web管理控制臺(tái)。
這篇文章,通過一個(gè)demo項(xiàng)目,演示了如何使用agenda來管理定時(shí)任務(wù)。
為什么需要管理定時(shí)任務(wù)最早用crontab管理來管理定時(shí)任務(wù)的時(shí)候,需要手動(dòng)去服務(wù)器上設(shè)置任務(wù),然后還要在服務(wù)器上部署定時(shí)執(zhí)行的程序。整個(gè)過程依賴手工操作,用起來感覺特別不踏實(shí)。那時(shí)候在想,應(yīng)該有一種更方便的管理定時(shí)任務(wù)的機(jī)制,所以盡量在設(shè)計(jì)上減少定時(shí)任務(wù)的使用,只在最必要的時(shí)候才會(huì)使用。
后來看了很多技術(shù)分享,看到知乎的分享他們的運(yùn)維系統(tǒng)的經(jīng)驗(yàn),實(shí)現(xiàn)了一個(gè)可以配置,并且有精美的管理后臺(tái)的定時(shí)任務(wù)管理系統(tǒng),能夠在運(yùn)維后臺(tái)方便的對(duì)任務(wù)進(jìn)行操作。
現(xiàn)在已經(jīng)可以簡單的使用agendash和agenda集成,就方便了實(shí)現(xiàn)了任務(wù)管理,從而可以更專注的實(shí)現(xiàn)業(yè)務(wù)邏輯
實(shí)現(xiàn)原理雖然不需要自己再去發(fā)明輪子是非常方便的事情,但是還是應(yīng)該試著去自己動(dòng)手做一些嘗試,實(shí)際實(shí)現(xiàn)起來成本比較高,但是思考一下如何實(shí)現(xiàn),還是有價(jià)值的。
agenda通過mongodb實(shí)現(xiàn)了任務(wù)在定時(shí)任務(wù)處理集群中的共享和鎖定,從而實(shí)現(xiàn)了分布式執(zhí)行定時(shí)任務(wù)的功能,實(shí)現(xiàn)了更高的可用性;
再結(jié)合作為express插件開發(fā)的agendash,我們就可以通過管理后臺(tái)查詢和管理定時(shí)任務(wù)。
實(shí)現(xiàn)思路如果我自己實(shí)現(xiàn)的話,首先要考慮定時(shí)任務(wù)如何設(shè)置,就是語法,agenda并沒有自己發(fā)明輪子,而是使用了已有的cron模塊,該模塊的定時(shí)任務(wù)配置語法,和crontab一樣,是形如*/5 * * * *的形式。
我們要考慮的是定時(shí)任務(wù)的機(jī)制,程序執(zhí)行之后,一直在進(jìn)程中輪詢,是否符合觸發(fā)條件,如果符合觸發(fā)條件,就會(huì)觸發(fā)設(shè)置的要執(zhí)行的業(yè)務(wù)邏輯相關(guān)代碼,crontab實(shí)際上也是觸發(fā)執(zhí)行shell腳本的代碼。最后由業(yè)務(wù)邏輯代碼根據(jù)自己的實(shí)際情況運(yùn)行。
任務(wù)的調(diào)用,可以用觀察者模式實(shí)現(xiàn)。在nodejs中,可以方便的使用回調(diào)函數(shù),將任務(wù)的名字和回調(diào)函數(shù)綁定,這樣,任務(wù)條件達(dá)到的時(shí)候,就會(huì)觸發(fā)執(zhí)行回調(diào)函數(shù);可以結(jié)合nodejs的queue隊(duì)列模塊來實(shí)現(xiàn)。
只有把任務(wù)用專有的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)起來,才有可能實(shí)現(xiàn)某種任務(wù)本身的邏輯,需要什么樣的邏輯,就需要什么樣的數(shù)據(jù)結(jié)構(gòu)做支撐。因此mongodb中要存儲(chǔ)的數(shù)據(jù)包括:執(zhí)行條件、任務(wù)名稱、創(chuàng)建時(shí)間、上次開始時(shí)間、上次完成時(shí)間、下次執(zhí)行時(shí)間、目前是否在鎖定狀態(tài)。
這樣,某個(gè)節(jié)點(diǎn)執(zhí)行是,正好符合條件,它先設(shè)置任務(wù)狀態(tài)為鎖定,然后調(diào)用回調(diào)函數(shù),完成之后,在解除鎖定,并且設(shè)置相應(yīng)的時(shí)間;如果出現(xiàn)程序意外崩潰,其他節(jié)點(diǎn)檢查是否超過一定處理時(shí)間,會(huì)將任務(wù)的鎖定狀態(tài)解除,然后接下來的其他節(jié)點(diǎn),就會(huì)檢查并且執(zhí)行任務(wù)。
使用agenda和agendashagenda本身運(yùn)行,是不需要web服務(wù)器;要使用agendash,目前必須安裝express,將agendash作為插件添加到express中,就可以正常的訪問。
演示程序的具體步驟如下:
安裝依賴包
搭建express腳手架
添加agenda任務(wù)和任務(wù)處理代碼
編寫簡單的測試
添加集成相關(guān)配置
安裝依賴包項(xiàng)目需要用到的依賴包分為三類,基本業(yè)務(wù)邏輯需要,es6編譯相關(guān)、還有測試依賴包。以下命令不包含babel相關(guān)依賴,請(qǐng)參看其他網(wǎng)上的教程。
npm install --saveagenda agendash express mongoose ejs npm install --save-dev mocha chai supertest搭建express腳手架和agendash
import path from "path" import "./config" import {agendash } from "./middlewares" var express = require("express"); var app = express(); var router = express.Router(); app.set("view engine","ejs"); app.set("views", "./views") app.set("view options",{ "open":"{{", "close":"}}" }); app.use(express.static("public")); ... ... app.use("/agendash", agendash); app.listen(8080, "0.0.0.0")
在express中通過app.use方法,可以加載路由,agendash作為一個(gè)插件,直接通過調(diào)用use方法,就可以添加到express的路由中,項(xiàng)目中,將agendash的相關(guān)路由,添加到/agendash下,這樣的話,訪問地址就是http://localhost:8080/agendash/#
添加agenda任務(wù)和任務(wù)處理代碼首先實(shí)例化一個(gè)agenda對(duì)象,設(shè)置mongodb數(shù)據(jù)庫連接地址,agenda會(huì)處理mongodb連接。
通過agenda實(shí)例的define方法,就可以綁定事件和處理函數(shù),第一個(gè)參數(shù)是事件名稱,第二個(gè)就是處理事件的回調(diào)函數(shù);因?yàn)樘幚硎沁^程是異步的,所以結(jié)束之后要調(diào)用done。
agenda在初始化完成之后,會(huì)回調(diào)綁定的ready方法,在ready中,我們就可以調(diào)用agenda的every函數(shù),創(chuàng)建新的定時(shí)任務(wù)。
將agenda實(shí)例作為參數(shù)傳給Agendash,后者就會(huì)生成能夠操作agenda實(shí)例的router。
var Agenda = require("agenda"); var Agendash = require("agendash"); var mongoConnectionString = config["agendaMongodbUrl"] var agenda = new Agenda({db: {address:mongoConnectionString}}) agenda.define("delete old users", function(job, done) { console.log("we will delete user here") done() }); agenda.on("ready", function() { //agenda.every("3 minutes", "delete old users"); agenda.every("*/5 * * * *", "delete old users"); agenda.start(); }); export default Agendash(agenda)編寫簡單的測試
完成編碼之后,我們通過supertest編寫簡單測試,檢查是否可以成功連接mongodb并啟動(dòng)agendash;要成功運(yùn)行測試,必須在本地安裝mongodb。
如代碼所示,我們會(huì)測試連接agendash的api接口,檢查返回的json數(shù)據(jù),是否符合我們創(chuàng)建的定時(shí)任務(wù)。如果一致,那么測試通過
const app = require("../lib") const request = require("supertest"); var assert = require("assert"); describe("GET /agendash/api", function () { it("should return the correct overview", function (done) { request(app).get("/agendash/api") .expect(200) .expect(function (res) { assert(res.body.title, "Agendash") }) .end(done) }) })添加集成相關(guān)配置
因?yàn)轫?xiàng)目使用了es6語法,所以需要集成babel才能運(yùn)行程序和測試。我們?cè)?b>package.json中,添加start和test命令的script,在運(yùn)行和測試的時(shí)候,都會(huì)用babel來實(shí)時(shí)編譯es6代碼。為了成功的運(yùn)行mocha測試,我們還需要設(shè)置.babelrc配置文件。
# package.json ... ... "scripts": { "start": "babel-node lib/index.js --presets es2015,stage-2", "test": "./node_modules/.bin/mocha --compilers js:babel-core/register ./test" } # .babelrc { "presets": ["es2015","stage-2"], "plugins": [] } ... ... # 然后我們就可以運(yùn)行程序 npm install npm start
如果不想自己安裝mongodb或者在本機(jī)安裝node_modules,項(xiàng)目的源代碼中提供了docker-compose配置文件,只需要運(yùn)行docker-compose up命令,就可以運(yùn)行服務(wù)。然后打開瀏覽器查看http://localhost:8080/agendash
示例代碼 https://github.com/liuwill-projects/agenda-cron-demo
文/liuwill(簡書作者)
原文鏈接:用agenda和agendash管理定時(shí)任務(wù)
著作權(quán)歸作者所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡書作者”。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/18976.html
摘要:通過實(shí)例的方法,就可以綁定事件和處理函數(shù),第一個(gè)參數(shù)是事件名稱,第二個(gè)就是處理事件的回調(diào)函數(shù)因?yàn)樘幚硎沁^程是異步的,所以結(jié)束之后要調(diào)用。 showImg(https://segmentfault.com/img/remote/1460000008845353); 在軟件系統(tǒng)的運(yùn)維中,總有一些事件,需要在特定的時(shí)間來觸發(fā)執(zhí)行,這個(gè)時(shí)候,我們需要用到定時(shí)任務(wù)。 agenda是nodejs實(shí)...
摘要:定義觸發(fā)規(guī)則我們的前端監(jiān)控,會(huì)主要追蹤三種報(bào)警情況錯(cuò)誤率達(dá)到設(shè)定閾值報(bào)警錯(cuò)誤率達(dá)到閾值報(bào)警訪問速度慢報(bào)警。郵件通知服務(wù)目前郵件通知服務(wù)也有很多,我們選的是阿里云的郵件推送。配置任務(wù)調(diào)度,創(chuàng)建實(shí)例配置阿里云郵件推送,這里使用方式去發(fā)送郵件。 所謂web,即使你我素未謀面,便知志趣相投;足不出戶,亦知世界之大。 ?01 - 什么是閾值報(bào)警功能 在我們前端監(jiān)控系統(tǒng)中,雖然我們收集了用戶實(shí)時(shí)訪...
摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...
摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...
摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...
閱讀 3267·2021-11-18 10:02
閱讀 3443·2021-10-11 10:58
閱讀 3376·2021-09-24 09:47
閱讀 1120·2021-09-22 15:21
閱讀 3915·2021-09-10 11:10
閱讀 3277·2021-09-03 10:28
閱讀 1748·2019-08-30 15:45
閱讀 2136·2019-08-30 14:22