在 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 部門,愛折騰,愛思考,愛老婆的程序猿一枚。