一 开发概述
对于具有一定规模的大多数企业来说,存在着这样一种需求:存在某个或某些任务,需要系统定期,自动地执行,然而,对大多数企业来说,该技术的实现,却是他们面临的一大难点和挑战。
对于大部分企业来说,实现如上功能,挑战在哪里?
挑战一:如何做一个自动服务的系统?
是从0到1开发(费时费力花钱,还不一定开发成功,即使开发成功,也未必好用),还是购买第三方服务(花钱)。
挑战二:如何实现复杂的“定期规则”?
对于简单的定期规则,可以借助于windows自带的执行计划来执行,但若是复杂的定期规则,windows执行计划未必可行,然而,Quartz的cron却很好地解决了该问题,
(可以说,cron在表达时间规则方面,无所不能),除此之外,Quartz能很好地配合windows执行计划,实现系统的定期,自动执行任务。
通过如上概述,我们知道Quartz能很好地解决该问题,那么,什么是Quartz呢?
简言之,Quartz就是一种任务调度计划。
- 它是由OpenSymphony提供的、开源的、java编写的强大任务调度框架
- 几乎可以集成到任何规模的运用程序中,如简单的控制台程序,复杂的大规模分布式电子商务系统
- 可用于创建简单的或复杂的计划任务
- 包含很多企业级功能,如支持JTA和集群等
本篇文章,主要从Quartz框架核心组件,Quartz基本运行原理,Quartz核心概念和Quartz基本功能实现(代码)等方面来介绍Quartz。
二 Quartz
当要深入研究一个技术时,研究它的体系结构和内部运行原理,不失为一种较好的方式。同理,我们在研究Quartz时,也采用类似的方法,
下图为Quartz的大致结构图。
(一)Quartz关键组件
Quartz比较关键的两个核心组件分别为Job和Trigger
- job--表示任务是什么
- trigger--表示何时触发任务
(二)Quartz几个关键概念
1.IJob
IJob表示一个接口,该接口只有一个方法签名
public interface IJob { void Execute(JobExecutionContext context); }
在Quartz中,所有的job任务,必须实现该接口
public class MyJob : IJob { public void Execute(JobExecutionContext context) { Console.WriteLine("Quartz基本功能测试。"); } }
2.JobDetail
JobDetail,顾名思义,就是表示关于每个Job的相关信息,它主要包括两个核心组件,即Job Task和JobData Map
3.Trigger
Trigger,表示触发器,根据配置规则来触发执行计划调度job,它主要包括两个核心组件,即SimpleTrigger和CronTrigger
4.IJobStore
IJobStore,表述任务存储器,主要存储job和trigger相关信息。
5.ISchedulerFactory
ISchedulerFactory,表示任务计划工厂,用来管理任务计划IScheduler。
6.IScheduler
IScheduler,表述任务计划,它相当于一个容器,具体job和job相关trigger就能够被注入其中,从而实现任务计划调度。其主要常用的方法:
- Start --启动执行计划
- Shutdowm --关闭执行计划
接口Code:
namespace Quartz { public interface IScheduler { bool IsStarted { get; } string SchedulerName { get; } string SchedulerInstanceId { get; } bool InStandbyMode { get; } bool IsShutdown { get; } IJobFactory JobFactory { set; } string[] JobGroupNames { get; } string[] TriggerGroupNames { get; } SchedulerContext Context { get; } IList GlobalJobListeners { get; } string[] CalendarNames { get; } IList GlobalTriggerListeners { get; } ISet TriggerListenerNames { get; } ISet JobListenerNames { get; } IList SchedulerListeners { get; } void AddCalendar(string calName, ICalendar calendar, bool replace, bool updateTriggers); void AddGlobalJobListener(IJobListener jobListener); void AddGlobalTriggerListener(ITriggerListener triggerListener); void AddJob(JobDetail jobDetail, bool replace); void AddJobListener(IJobListener jobListener); void AddSchedulerListener(ISchedulerListener schedulerListener); void AddTriggerListener(ITriggerListener triggerListener); bool DeleteCalendar(string calName); bool DeleteJob(string jobName, string groupName); ICalendar GetCalendar(string calName); string[] GetCalendarNames(); IList GetCurrentlyExecutingJobs(); IJobListener GetGlobalJobListener(string name); ITriggerListener GetGlobalTriggerListener(string name); JobDetail GetJobDetail(string jobName, string jobGroup); IJobListener GetJobListener(string name); string[] GetJobNames(string groupName); SchedulerMetaData GetMetaData(); ISet GetPausedTriggerGroups(); Trigger GetTrigger(string triggerName, string triggerGroup); ITriggerListener GetTriggerListener(string name); string[] GetTriggerNames(string groupName); Trigger[] GetTriggersOfJob(string jobName, string groupName); TriggerState GetTriggerState(string triggerName, string triggerGroup); bool Interrupt(string jobName, string groupName); bool IsJobGroupPaused(string groupName); bool IsTriggerGroupPaused(string groupName); void PauseAll(); void PauseJob(string jobName, string groupName); void PauseJobGroup(string groupName); void PauseTrigger(string triggerName, string groupName); void PauseTriggerGroup(string groupName); bool RemoveGlobalJobListener(IJobListener jobListener); bool RemoveGlobalJobListener(string name); bool RemoveGlobalTriggerListener(ITriggerListener triggerListener); bool RemoveGlobalTriggerListener(string name); bool RemoveJobListener(string name); bool RemoveSchedulerListener(ISchedulerListener schedulerListener); bool RemoveTriggerListener(string name); DateTime? RescheduleJob(string triggerName, string groupName, Trigger newTrigger); void ResumeAll(); void ResumeJob(string jobName, string groupName); void ResumeJobGroup(string groupName); void ResumeTrigger(string triggerName, string groupName); void ResumeTriggerGroup(string groupName); DateTime ScheduleJob(Trigger trigger); DateTime ScheduleJob(JobDetail jobDetail, Trigger trigger); void Shutdown(bool waitForJobsToComplete); void Shutdown(); void Standby(); void Start(); void StartDelayed(TimeSpan delay); void TriggerJob(string jobName, string groupName); void TriggerJob(string jobName, string groupName, JobDataMap data); void TriggerJobWithVolatileTrigger(string jobName, string groupName); void TriggerJobWithVolatileTrigger(string jobName, string groupName, JobDataMap data); bool UnscheduleJob(string triggerName, string groupName); } }
(三)核心UML图
1.命名空间
不同版本的Quartz命名空间有所区别,但差别不大,如下为版本1.0.3命名空间
using Quartz; using Quartz.Core; using Quartz.Impl; using Quartz.Impl.AdoJobStore; using Quartz.Impl.AdoJobStore.Common; using Quartz.Impl.Calendar; using Quartz.Impl.Matchers; using Quartz.Impl.Triggers; using Quartz.Listener; using Quartz.Logging; using Quartz.Logging.LogProviders; using Quartz.Simpl; using Quartz.Spi; using Quartz.Util; using Quartz.Xml; using Quartz.Xml.JobSchedulingData20; using System;
2.关键组件继承关系
在Quartz中,许多组件是可以通过配置来促使作业执行的,如线程程序(Tread Procedure)决定如何执行计划任务线程(Quartz Scheduler Thread)
三 代码
本示例,我们将使用.net 控制台程序,基于VS2017来使用Quartz建立一个任务:
任务要求:要求在控制台每隔2秒输出:Quartz基本功能测试。
1.首先使用Nuget下载Quartz
本示例使用的Quartz版本为1.0.3
2.按照如下步骤操作
代码:
第一阶段:创建实现IJob接口的MyJob类
public class MyJob : IJob { public void Execute(JobExecutionContext context) { Console.WriteLine("Quartz基本功能测试。"); } }
第二阶段:按规则调用Quartz组件
static void Main(string[] args) { //每个2秒执行一次 string cronParam = "*/2 * * * * ?"; //创建计划任务抽象工厂 ISchedulerFactory sf = new StdSchedulerFactory(); //创建计划任务 IScheduler sched = sf.GetScheduler(); //创建job JobDetail job = new JobDetail("myJob","group", typeof(MyJob)); //创建触发器 Trigger trigger = new CronTrigger("myTrigger","group",cronParam); //将job和trigger注入到计划任务中 sched.ScheduleJob(job, trigger); //启动计划任务 sched.Start(); //关闭计划任务 //sched.Shutdown(); Console.Read(); }
3.测试结果
四 参考文献
【01】http://www.quartz-scheduler.org/
【02】https://www.ibm.com/developerworks/library/j-quartz/index.html
【03】https://www.w3cschool.cn/quartz_doc/
五 版权区
- 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
- 博主网址:http://www.cnblogs.com/wangjiming/。
- 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
- 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。
- 可以转载该博客,但必须著名博客来源。