作者|伊星宇
動態定時任務,就是在不重啟服務的狀態下,可以做到繼續添加,更新已有,刪除已有任務。定時任務有很多實現的方式,包括timer,timertask,scheduledexecutorservice,以及第三方框架Quartz。本篇文章主要介紹SpringBoot整合Quartz實現動態定時任務。
1、Quartz是功能強大的開源作業調度庫,可以創建簡單或複雜的計劃,可以運行十個,百個,甚至幾萬個Jobs這樣複雜的日程序表。
2、quartz的基本組成如下:
Scheduler - 核心調度器,scheduler被用來對Trigger和Job進行管理
Job - 任務,Job是一個任務接口,需要實現該接口execute方法
JobDetail - 任務描述,JobDetail是任務的定義,而Job是任務的執行邏輯
Trigger - 觸發器,Trigger是用來定義Job的執行規則,主要有四種觸發器,其中 SimpleTrigger和CronTrigger使用最多
Quarqz的應用
Quartz的典型使用場景,主要就是用來執行定時任務,例如:定時發送信息,定時生成報表,自動更新靜態數據等等。接下來結合接口測試平臺,首先看看需求中定時任務要實現的功能,如下圖:
其中主要功能包括創建,編輯,刪除,暫停,恢復等基本功能,對於創建定時任務的規則,按照每天指定時間,或者間隔多少小時循環執行定時任務,循環次數是可進行限制的。最重要的當用戶操作時,在作業調度scheduler中,動態添加,更新,刪除任務等,不需要重啟服務即可實現。
1、在工程pom文件中,添加依賴
2、添加配置
因為springBoot已經集成了quartz,所以直接配置application.yaml文件即可;這裡使用了quartz的默認配置,所以沒有在yaml文件中自定義定時任務的配置,這裡說下quartz的兩種基本作業存儲類型RAMJobStore和JDBC作業存儲,兩種類型的優缺點如下:
RAMJobStore
JDBC作業存儲
因為本篇採用默認配置,所以存儲類型是RAMJobStore。同樣,可以根據項目特點進行切換,需要在application.yaml配置中增加如下配置信息,以及按照官方文檔提供sql創建數據表。本篇不過多介紹這種方式。
3、添加quartz配置
spring通過SchedulerFactoryBean來管理Quartz的生命周期。在spring啟動容器時啟動調度器,在spring關閉容器時關閉調度器。
4、創建任務,實現Job,其只有一個方法execute方法,主要編寫定時任務的處理邏輯。
5、定義定時任務的操作
包括服務啟動時開始執行全部任務timingTask,新增addJob,更新updateJob,操作operateJob(刪除,暫停,恢復)。
服務層對接口進行實現,將觸發器Trigger設定的觸發規則,以及任務描述JobDetail,交給作業調度Scheduler進行管理。
這裡的觸發器採用的是SimpleTrigger。
6、定義接口
將用戶提交的信息保存到資料庫中,同時調用創建定時任務的接口,將它交給調度作業Scheduler進行管理,這樣實現了動態的定時任務,不需要進行停機再啟動就可以添加,編輯等,對正在運行任務進行操作。
7、定時任務表設計如下圖:
8、執行效果如下圖:
9、服務啟動時,將所有表中已存在任務添加到調度作業進行管理。
註:SpringBoot在項目啟動後會遍歷所有實現CommandLineRunner的實體類並執行run方法。
到這裡本篇介紹的內容就結束了,Quartz功能的確很強大,與SpringBoot的框架整合也很方便,可以滿足很多複雜的調度需求,對於初次接觸Quartz的我來說,上手還是相對比較簡單方便,在這裡給大家提個醒,所有的技術,不是越高端越好,而是要根據需求選擇適合的技術去實現。
友情提醒:
1、如果採用內存作業存儲類型,重啟後執行次數會被清零,所以有這方面需求的小夥伴,記得採用資料庫作業存儲類型;
2、針對於Quartz集群部署情況,建議採用資料庫作業存儲類型,因為集群中每個節點是一個獨立的Quartz應用,該集群需要分別對每個節點進行啟動和停止操作,不像普通的服務集群。Quartz應用是通過資料庫表來感知另一個應用,只有持久化的JobStore才能完成Quartz集群。如果採用內存作業存儲類型,分布式部署需要增加鎖機制,例如:redis鎖等,防止重複多次執行。