AutoJob動態(tài)任務調度框架
AutoJob是一款輕量級任務調度框架,具有分布式、全異步、易拓展、易集成等特點,提供多種任務調度模式和多種任務類型。配置豐富、拓展方便、使用簡單、代碼侵入性低。
版本更新
2022-11-22: 初版0.9.1
2022-12-9: 0.9.2
優(yōu)化API。
核心調度模塊停止使用緩存時間戳,解決時間精度低的問題。
重構注解調度器。
重構執(zhí)行器池,新增基于時間動態(tài)調整的線程池封裝TimerThreadPoolExecutorHelper。
修改已知BUG。
調整項目結構。
2022-12-26: 新增Rest接口:鏈接: https://www.apifox.cn/apidoc/shared-05120000-4d19-4c75-a7f6-dc56105972cb 訪問密碼 : autojob
2022-12-27: 優(yōu)化子任務處理邏輯,新增任務MissFire事件
2022-12-29: 增加多數據庫適配,目前支持mysql,postresql
2023-1-3:
優(yōu)化重試機制,每個任務可單獨配置重試邏輯
優(yōu)化郵件報警機制,每個任務可單獨配置郵箱
新增任務重試事件TaskRetryEvent
調度記錄表新增is_retry屬性,表明該條調度記錄是否是由于異常進行重試的調度記錄
其他已知BUG
2023-3-14: 0.9.3
內置RPC框架編解碼器改為使用ProtoStuff,簡化API。
配置支持嵌套配置,內容可以通過VMOptions等給出,保護系統(tǒng)安全。
支持環(huán)境變量,便于在測試環(huán)境和生產環(huán)境切換。見:“四、環(huán)境變量”
2023-3-28: 0.9.4
對任務表進行拆分,目前拆分成aj_method_job和aj_script_job便于后期任務類型拓展。 注意0.9.4版本與之前版本的數據庫結構不兼容
優(yōu)化日志處理邏輯,從處理器私有處理線程到loop輪詢,避免并發(fā)任務過多導致線程資源耗盡。
新增任務運行上下文、任務運行堆棧,便于故障恢復等。具體見“九、任務運行上下文;十一、所有配置”。
新增模板任務,更加優(yōu)雅地開發(fā)任務。具體見:“十二、高級用法-注解任務開發(fā)的高級應用-@TemplateAutoJob”。
2023-7-12: 0.9.5
解決日志存在的BUG:日志消息隊列不清空的問題。 解決集群部署時重復啟動的問題。 新增任務屬性:executableMachines,用于指定執(zhí)行機器,只有地址匹配的機器方可執(zhí)行。數據庫結構有變動(aj_method_job和aj_script_job新增executable_machines列),可以根據SQL腳本自行新增,不要直接執(zhí)行腳本,否則會造成數據丟失。
2023-7-12: 0.9.6 最新
新增功能:
- 任務并發(fā)運行:同一個任務可以同時運行多個實例。
- 任務故障轉移:重試策略新增故障轉移策略,在開啟集群模式時有效,異常的任務會選擇一個“較好的”節(jié)點進行故障轉移執(zhí)行。
- 任務動態(tài)分片:在集群模式下支持分片任務,節(jié)點會自動感知當前集群節(jié)點數目,根據集群情況動態(tài)分片。
- 任務保存策略:支持不存在時保存、創(chuàng)建一個新的版本、存在則更新策略。
- 注解式腳本任務:可以直接在一個Java方法上使用
@ScriptJob注解來定義一個腳本任務,支持動態(tài)命令行。 - 函數任務:可以非常簡單的將一些業(yè)務邏輯交由AutoJob管理,AutoJob會為這些業(yè)務邏輯提供故障重試、過長中斷、日志存儲的功能。
其他性能優(yōu)化和BUG解決。
更新說明:
本次更新涉及數據庫結構變動,需要重新執(zhí)行SQL腳本,請先備份數據。
一、背景
生活中,業(yè)務上我們會碰到很多有關作業(yè)調度的場景,如每周五十二點發(fā)放優(yōu)惠券、或者每天凌晨進行緩存預熱、亦或每月定期從第三方系統(tǒng)抽數等等,Spring和java目前也有原生的定時任務支持,但是其都存在一些弊病,如下:
- 不支持集群,未避免任務重復執(zhí)行的問題
- 不支持生命周期的統(tǒng)一管理
- 不支持分片任務:處理有序數據時,多機器分片執(zhí)行任務處理不同數據
- 不支持失敗重試:出現異常任務終結,不能根據執(zhí)行狀態(tài)控制任務重新執(zhí)行
- 不能很好的和企業(yè)系統(tǒng)集成,如不能很好的和企業(yè)系統(tǒng)前端集成以及不能很好的嵌入到后端服務
- 不支持動態(tài)調整:不重啟服務情況下不能修改任務參數
- 無報警機制:任務失敗之后沒有報警通知(郵箱、短信)
- 無良好的執(zhí)行日志和調度日志跟蹤
基于原生定時任務的這些弊病,AutoJob就由此誕生,AutoJob為解決分布式作業(yè)調度提供了新的思路和解決方案。
二、特性
簡單: 簡單包括集成簡單、開發(fā)簡單和使用簡單。
集成簡單:框架能非常簡單的集成到Spring項目和非Spring項目,得益于AutoJob不依賴于Spring容器環(huán)境和MyBatis環(huán)境,你無需為了使用該框架還得搭建一套Spring應用。
開發(fā)簡單:AutoJob開發(fā)初衷就希望具有低代碼侵入性和快速開發(fā)的特點,如下在任意一個類中,你只需要在某個需要調度的任務上加上注解,該任務就會被框架進行動態(tài)調度:
@AutoJob(attributes = "{'我愛你,心連心',12.5,12,true}", cronExpression = "5/7 * * * * ?")
public void formatAttributes(String string, Double decimal, Integer num, Boolean flag) {
//參數注入
AutoJobLogHelper logger = new AutoJobLogHelper();//使用框架內置的日志類
logger.setSlf4jProxy(log);//對Slf4j的log進行代理,日志輸出將會使用Slf4j輸出
logger.info("string={}", string);
logger.warn("decimal={}", decimal);
logger.debug("num={}", num);
logger.error("flag={}", flag);
//使用mapper
mapper.selectById(21312L);
//...
}
使用簡單:使用該框架你無需關注太多的配置,整個框架的啟動只需要一行代碼,如下:
//配置任務掃描包路徑
@AutoJobScan({"com.yourpackage"})
//處理器自動掃描
@AutoJobProcessorScan({"com.yourpackage"})
public class AutoJobMainApplication {
public static void main(String[] args) {
//框架啟動
new AutoJobBootstrap(AutoJobMainApplication.class)
.build()
.run();
System.out.println("==================================>系統(tǒng)創(chuàng)建完成");
}
}
得益于良好的系統(tǒng)架構和編碼設計,你的應用啟動無需過多配置,只需要一行代碼
動態(tài): 框架提供API,支持任務的動態(tài)CURD操作,即時生效。
多數據庫支持: 提供多類型數據庫支持,目前支持MySQL、PostgreSQL、Oracle、DamengSQL,理論支持SQL標準的所有數據庫。
任務依賴: 支持配置子任務,當父任務執(zhí)行結束且執(zhí)行成功后將會主動觸發(fā)一次子任務的執(zhí)行。
一致性: 框架使用DB樂觀鎖實現任務的一致性,在集群模式下,調度器在調度任務前都會嘗試獲取鎖,獲取鎖成功后才會進行該任務的調度。
HA(新): 該框架支持去中心化的集群部署,集群節(jié)點通過RPC加密通信。集群節(jié)點之間會自動進行故障轉移。
彈性增縮容(新): 支持節(jié)點的動態(tài)上下線,同時節(jié)點支持開啟保護模式,防止惡劣的網絡環(huán)境下節(jié)點脫離集群。
任務失敗重試(新): 支持故障轉移和本地重試。
完整的生命周期: 框架提供任務完整的生命周期事件,業(yè)務可捕捉并做對應的處理。
動態(tài)調度線程池: 框架使用自研的動態(tài)線程池,可靈活根據任務流量動態(tài)調整線程池核心線程和最大線程參數,節(jié)省系統(tǒng)線程資源,并且提供了默認的拒絕處理器,防止任務被missFire。
異步非阻塞的日志處理: 日志采用生產者消費者模型,基于自研的內存消息隊列,任務方法作為日志的生產者,生產日志放入消息隊列,框架啟動對應的日志消費線程進行日志處理。
實時日志: 日志將會實時的進行保存,便于跟蹤。
任務白名單: 提供任務白名單功能,只有在白名單中的任務才允許被注冊和調度,保證系統(tǒng)安全。
可拓展的日志存儲策略: 日志支持多種策略保存,如內存Cache、數據庫等,可根據項目需要靈活增加保存策略,如Redis、文件等。
豐富的調度機制: 支持Cron like表達式,repeat-cycle調度、子任務觸發(fā)、延遲觸發(fā)等,得益于良好的編碼設計,用戶可非常簡單的新增自定義調度器,如下:
/**
* 你的自定義調度器
* @Author Huang Yongxiang
* @Date 2022/08/18 14:56
*/
public class YourScheduler extends AbstractScheduler{
public YourScheduler(AutoJobTaskExecutorPool executorPool, IAutoJobRegister register, AutoJobConfigHolder configHolder) {
super(executorPool, register, configHolder);
}
//...調度邏輯
}
@AutoJobScan("com.example.autojob.job")
@AutoJobProcessorScan("com.example.autojob")
public class AutoJobMainApplication {
public static void main(String[] args) {
new AutoJobLauncherBuilder(AutoJobMainApplication.class)
.withAutoScanProcessor()
//配置你的調度器
.addScheduler(YourScheduler.class)
.build()
.run();
System.out.println("==================================>系統(tǒng)創(chuàng)建完成");
}
}
任務報警: 框架支持郵件報警,目前原生支持QQ郵箱、163郵箱、GMail等,同時也支持自定義的郵箱smtp服務器。
目前系統(tǒng)提供:任務失敗報警、任務被拒報警、節(jié)點開啟保護模式報警、節(jié)點關閉保護模式報警,當然用戶也可非常簡單的進行郵件報警的拓展。
豐富的任務入參: 框架支持基礎的數據類型和對象類型的任務入參,如Boolean,String,Long,Integer,Double等類型,對于對象入參,框架默認使用JSON進行序列化入參。
良好的前端集成性: 框架提供相關API,用戶可以靈活開發(fā)Restful接口接入到企業(yè)項目,無需額外占用一個進程或機器來單獨運行調度中心。
內存任務: 框架提供DB任務和內存任務兩種類型,DB任務持久化到數據庫,聲明周期在數據庫內記錄,內存任務除了日志,整個生命周期都在內存中完成,相比DB任務具有無鎖、調度快速的特點。
腳本任務: 提供腳本任務的執(zhí)行,如Python、Shell,SQL等。
動態(tài)分片(新): 集群模式下框架支持任務分片,多機運行。
全異步: 任務調度流程采用全異步實現,如異步調度、異步執(zhí)行、異步日志等,有效對密集調度進行流量削峰,理論上支持任意時長任務的運行。
