无需Get更多技能,快速打造一个可持久化的任务调度
項目總是很忙,忙里偷閑還是要總結一下,前一段時間,由于項目中需要,我們需要很多定時匯總數據的情況,項目初期主要使用sql server 計劃任務實現對數據的匯總與統計,但是開發到一定時間內,需求提出了很多自動任務的功能,很多不是能夠在SQL Server中進行解決的,例如訂單關閉前多少分鐘內發短信與郵箱告訴用戶,程序層面每天匯總錯誤日志發送至運維郵箱等,針對目前情況,簡單上網查了一下,決定使用TopShelf + Quartz 進行自動服務與任務調度,關于這兩項的介紹也很多了,廢話不多說,直接上代碼:
-
項目結構圖如下:
?
任務調度與任務實現實質是兩個完全不同的東西,所以自動服務于Job執行是應該分開的,所以任務創建時應該吧Job加載到任務調度工程,最后告訴調度工廠,可以開始執行任務之后,調度工廠會進行掃描Job,加載到內存中挨個執行。
-
IAutoService:?主要是聲明自動服務的接口模式,標記了服務的名稱,啟動時的加載等,統一由抽象類AutoServcieBase實現。
-
AutoServiceBase: 抽象類實現接口原則,規范自動任務的可選參數,統一封裝調用,定義抽象方法與屬性,子類重寫。
定義好基礎服務后,接下來我們就要使用TopShelf搭建一個屬于我們自己的windows service了,代碼如下:
class Program{static void Main(string[] args){HostFactory.Run(x =>{x.Service<Service>(s =>{s.ConstructUsing(name => new Service());s.WhenStarted(tc => tc.Start());s.WhenStopped(tc => tc.Stop());s.WhenShutdown(tc => tc.Shutdown());});x.RunAsLocalSystem();x.SetDescription("服務集合,包含自動化消息,響應隊列的領域事件");x.SetDisplayName("Test.Services");x.SetServiceName("Test.Services");});}}??topshelf是一個很簡單就能創建service的工具,它開源在GitHub TopShelf上,是一款快速搭建mono與windows service ,在編寫好我們的服務代碼,只需簡單地啟動代碼,就能創建一個持久化的服務,不過想要兼容在Mono上也是非常簡單,只需加入如下一句代碼即可。
x.UseLinuxIfAvailable();?在我們的項目中windows service不僅僅是任務調度的寄宿形式,同時也是我們Event Store,對DDD感興趣的同學可以了解CQRS中SAGA模式中事件消費的形式,這個不在本文討論。
創建好我們的基礎服務后,接下來就是對任務調度工廠的設置,任務調度簡單來看,我們往往要使用事件監聽,任務總調度工廠等等,這里Quartz很好的集成了這些,我們只需進行簡單的改造就能夠實現如上功能。
-
QuartzScheduleJobManager:實現任務調度管理,在這里可以對總任務調度工廠進行啟動,停止,加載Job等
IQuartzConfiguration是對IScheduler的一個簡單封裝,創建默認的調度程序:
1 public class QuartzConfiguration : IQuartzConfiguration 2 { 3 public IScheduler Scheduler => StdSchedulerFactory.GetDefaultScheduler(); 4 }?接下來就是任務監聽,Quartz提供了一個很好的擴展,我們只需實現IJobListener接口即可,包含如下多個方法體:
查看字面意思,我們就能很好理解就是對每一個job在執行中的階段所對應的事件,方法體內給出IJobExecutionContext當前執行的上下文,通過上下文我們可以輸出許多我們想要的東西,例如當前執行Job的Name,執行時間,等等,也提供了JobExecutionException等異常信息,可以監控Job執行過程中發生的錯誤,很方便。
好了在我們的寄宿服務,與基礎服務搭建完畢后,接下來就是要實現在業務系統中我們自身的邏輯結構了,核心程序類Servcie.cs,在service中我們需要將我們如上的配置進行加載,并同時掃描我們業務系統中的定時服務類,挨個進行啟動,代碼如下:
?
public class Service{/// <summary>/// 任務調度框架/// </summary>private IQuartzScheduleJobManager QuartzScheduleJobManager{get{return IocManager.Instance.Resolve<IQuartzScheduleJobManager>();}}/// <summary>/// 任務調度配置/// </summary>public IQuartzConfiguration QuartzConfiguration{get{return IocManager.Instance.Resolve<IQuartzConfiguration>();}}public Service(){try{//注冊我們的任務調度程序配置
IocManager.Register<IQuartzConfiguration, QuartzConfiguration>();
//注冊任務監聽程序到Ioc
?IocManager.Register<IJobListener, QuartzJobListener>();
//聲明一個接口可以被多個實例實現IocManager.IocContainer.Kernel.Resolver.AddSubResolver(new ArrayResolver(TongTongMallBootstrapper.IocManager.IocContainer.Kernel, true));}catch (Exception ex){LogHelper.LogException(ex);}}
//設置我們的配置項public void QuartzConfigurationInitialize(){//Job映射工廠QuartzConfiguration.Scheduler.JobFactory = new QuartzJobFactory(IocManager.Instance);//Job 監聽配置QuartzConfiguration.Scheduler.ListenerManager.AddJobListener(IocManager.Instance.Resolve<IJobListener>());}/// <summary>/// 基礎類服務/// </summary>public void Start(){//訂閱各項自動服務IocManager.Instance.IocContainer.Register(Classes.FromThisAssembly().BasedOn<IAutoService>().WithService.Base()); QuartzConfigurationInitialize();RegisterService();}/// <summary>/// 停止自動服務/// </summary>public void Stop(){QuartzScheduleJobManager.ShutDown();}/// <summary>/// 結束自動服務/// </summary>public void Shutdown(){TongTongMallBootstrapper.Dispose();QuartzScheduleJobManager.ShutDown();}/// <summary>/// 注冊服務/// </summary>/// <param name="args"></param>public void RegisterService(){foreach (var service in IocManager.Instance.IocContainer.ResolveAll<IAutoService>()){if (service.IsEnable){LogHelper.Logger.Debug($"{service.ServiceName}服務正在啟動中...");service.Start();}}LogHelper.Logger.Debug($"任務總調度工廠啟動!");QuartzScheduleJobManager.Start();}}
?在系統中我們主要使用了IOC進行了一個服務的自動掃描與切入,在服務配置完畢后,接下來我們只需定義業務相關的自動服務即可,通過繼承我們的抽象類AutoServiceBase,接下來就很方便的打造每一個自動任務調度了,而關于Quartz的任務調度形式與時間配置,不是本文的重點介紹內容,就不在詳說,不過在任務調度中我們也可以實現很多自定義的時間調度模式,例如自定義的節假日,或者每周一執行任務調度都可以,這個需要進行進一步編碼實現。
由于公司方面,代碼就不在給連接資源下載了,代碼給出只是思路,當然在這里面還可以有更多的擴展,而本文只是方便快速上手為第一原則,文章有寫的不當的地方,請及時指出,如本文對您有所幫助,也請點個推薦,您的肯定也是是我最大的動力。thanks
轉載于:https://www.cnblogs.com/doNetTom/p/6442201.html
總結
以上是生活随笔為你收集整理的无需Get更多技能,快速打造一个可持久化的任务调度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hibernate查询-基本查询
- 下一篇: 提高Web性能的前端优化技巧总结