文章出處

回到目錄

在DotNetCore出來之后,同時也使用了quartz進行調度中心的設計,將它做到docker里方便部署,在之前的quartz版本里支持配置文件的方式,而現在不支持了,我們應該去想一下,為什么不去支持配置文件?當然大叔也為配置文件設計了支持的方式,但我們還是應該想想作者為什么不去支持配置?

熱插拔,服務發現?

和上面兩個概念可能有點關系,熱插拔很容易理解,就是把dll模塊放到正在運行的項目時,它可以直接啟動,這個功能對調度中心來說,很是必要,因為你可能需要按著不同的功能設計一些服務job,而這些服務沒有什么聯系,每個job功能單一,如果做成熱部署,挺好!而服務發現在最近<微服務>里很是槍眼,今天說的服務發現并不是它,而是dotnet core公開的對文件夾的監控,其實就是一種事件機制,當windows底層文件夾改變時(增,刪,改文件),會向上觸發對應的事件,而我們只要去訂閱它即可,非常的松耦合!

公開的事件

       var watcher = new FileSystemWatcher();
            watcher.Path = AppDomain.CurrentDomain.BaseDirectory;
            watcher.NotifyFilter = NotifyFilters.Attributes |
                                   NotifyFilters.CreationTime |
                                   NotifyFilters.DirectoryName |
                                   NotifyFilters.FileName |
                                   NotifyFilters.LastAccess |
                                   NotifyFilters.LastWrite |
                                   NotifyFilters.Security |
                                   NotifyFilters.Size;
            watcher.Filter = "*.dll";
            // quartz運行時,可以添加新job,但不能覆蓋,刪除等
            watcher.Created += new FileSystemEventHandler((o, e) =>
            {
                foreach (var module in Assembly.LoadFile(e.FullPath).GetModules())
                {
                    foreach (var type in module.GetTypes().Where(i => i.BaseType == typeof(JobBase)))
                    {
                        JoinToQuartz(type);
                    }
                }
            });

            //Start monitoring.
            watcher.EnableRaisingEvents = true;

將job添加到Quartz需要在初始化和文件夾監控兩個地方用到,所以我們進行了抽象,把它提到一個委托里,使用.net4.0的Actioin<T>委托來實現最為合適了!

          Action<Type> JoinToQuartz = (type) =>
            {
                var obj = Activator.CreateInstance(type);
                string cron = type.GetProperty("Cron").GetValue(obj).ToString();
                var jobDetail = JobBuilder.Create(type)
                                          .WithIdentity(type.Name)
                                          .Build();

                var jobTrigger = TriggerBuilder.Create()
                                               .WithIdentity(type.Name + "Trigger")
                                               .StartNow()
                                               .WithCronSchedule(cron)
                                               .Build();

                StdSchedulerFactory.GetDefaultScheduler().Result.ScheduleJob(jobDetail, jobTrigger);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"新添加了一個服務{nameof(type)},通過心跳Job自動被加載!");
            };

大叔把它應用到了調度中心上,具體就是當調試項目里有新的模塊DLL出現后,自動將它添加到quartz的列表里,然后當然它有自己的cron表達式去控制自己的調度周期,你是定點地還是周期運行完成由自己的job去控制,如果有新功能,就加新Job,是否有點單一職責和開閉原則的意思!

JobBase,所有模塊的功能Job都要繼承它,可以根據自己的情況,實現cron和業務ExcuteJob方法!

  [DisallowConcurrentExecution()]
    public abstract class JobBase : IJob
    {

        #region IJob 成員

        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(DateTime.Now.ToString() + "{0}這個Job開始執行", context.JobDetail.Key.Name);
                ExcuteJob(context);
                return Task.CompletedTask; ;
            }
            catch (Exception ex)
            {
                LoggerFactory.CreateLog().Logger_Debug(this.GetType().Name + "error:" + ex.Message);
                throw;
            }
        }

        #endregion
        /// <summary>
        /// 執行計劃,子類可以重寫
        /// </summary>
        public virtual string Cron => "0/5 * * * * ?";
        /// <summary>
        /// Job具體類去實現自己的邏輯
        /// </summary>
        protected abstract void ExcuteJob(IJobExecutionContext context);

    }

下面看其中一個業務Job的實現,它主要由調度計劃cron和業務執行方法ExcuteJob組成

   /// <summary>
    /// 發送消息
    /// </summary>
    public class SendEmailJob : JobBase
    {
        public override string Cron => "0/2 * * * * ?";

        protected override void ExcuteJob(IJobExecutionContext context)
        {
            Console.WriteLine("發送Email");
            LoggerFactory.CreateLog().Logger_Debug("發送Email:" + DateTime.Now);
        }
    }

當我們把這個項目發布到dotnet core之后,可以設計一個web api /web mvc管理UI,然后去查看和管理自己的任務,現在quartz2.x里的crystal管理工具已經用不了了,所以咱們還是DIY一下吧!哈哈!

可以查看任務列表,管理它們的啟動與停止的狀態!

感謝各位的閱讀!

回到目錄


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()