ScheduleMaster在上個月底更新到了2.0版本,在功能和代碼以及文檔上都往前跨了很大一步,詳細信息能夠參考這篇文章:http://www.javashuo.com/article/p-ocmxdrtm-ga.htmlhtml
對ScheduleMaster還不熟悉的朋友能夠先移步做者的系列文章:https://www.cnblogs.com/hohoa/category/1628282.htmlgit
此次的更新點主要包含:github
開發了延時任務功能。算法
抽象出分佈式鎖服務並默認數據庫實現。數據庫
補充了單元測試。c#
補充了幾篇文檔。api
修復了已知的bug。dom
其中的重頭戲天然是延時任務功能,所謂的延時任務就是在指定時刻執行指定邏輯,這在平時需求開發中是很是常見的,做爲一款功能齊全的調度系統這固然也是必備的功能。分佈式
關於延時任務的實現原理我早期寫過一篇文章《採用簡易的環形延時隊列處理秒級定時任務的解決方案》來介紹,ScheduleMaster也是在這個基礎上改進而來。post
固然了,其餘的實現方式也還有不少,主流的實現方案能夠參考下面這篇文章,整理的比較齊全:http://www.javashuo.com/article/p-gvpspray-bc.html
我採用的就是比較經典的時間輪算法,原理就再也不重複介紹了能夠移步到我前面的文章,下面看看實現效果。
咱們先經過一段測試代碼看看延時隊列的運行狀況:
[Fact] public void Run() { //初始化容器 DelayPlanManager.Init(); Debug.WriteLine($"延時隊列初始化完成時間:{DateTime.Now}"); Func<DelayQueueSlot, Task> callback = (result) => { var np = result as NotifyPlan; //模擬業務 Debug.WriteLine($"[{DateTime.Now}]ID:{np.Key},地址:{np.NotifyUrl},延遲秒數:{np.TimeSpan}"); return Task.CompletedTask; }; //模擬生產端寫入任務 Task[] tasks = new Task[10]; for (int i = 0; i < 10; i++) { tasks[i] = new Task(() => { for (int k = 0; k < 200; k++) { int rndNum = new Random().Next(20, 500); DelayPlanManager.Insert(new NotifyPlan { NotifyUrl = "http://localhost:56655/api/1.0/value/delaypost", Key = Guid.NewGuid().ToString(), Callback = callback }, DateTime.Now.AddSeconds(rndNum)); } }, TaskCreationOptions.LongRunning); tasks[i].Start(); } Task.WaitAll(tasks); //構造消費者 while (true) { DelayPlanManager.Read(); System.Threading.Thread.Sleep(1000); } }
代碼中建立了2000個延時任務,延時範圍在20秒至500秒,因此咱們預測在程序啓動後最快20秒就開始有信息輸出,程序調式結果爲:
當一個週期執行完後恰好過了1分鐘:
分秒不差。
再看看在項目中的實際應用。
控制檯建立任務頁面:
不過實際使用中經過API方式建立顯然更符合需求,因此一如既往地提供了開放API供業務系統接入,詳細使用方式參考官方文檔【使用API接入任務】。
系統提供了2種延遲模式供選擇,即相對時間或絕對時間,能夠在系統參數中配置,默認是使用相對時間。但使用相對時間模式有一點要注意,各節點間可能存在系統時間差致使任務被屢次執行,因此業務作好冪等性控制相當重要。
延時任務管理頁面:
這裏解釋下任務的各個狀態
已做廢,表示已經從執行計劃移除
已建立,表示剛建立好尚未加入執行計劃
已就緒,表示已加入到執行計劃中等待執行
已完成,表示執行成功
異常,表示執行失敗
繼續看一下任務運行狀況。
單節點執行成功:
異常重試效果:
可用的參數配置:
更多好玩的東西歡迎下載體驗~
喜歡的朋友請來一波star支持,並持續關注~~
傳送門: