一 开发概述
对于具有一定规模的大多数企业来说, 存在着这样一种需求: 存在某个或某些任务, 需要系统定期, 自动地执行, 然而, 对大多数企业来说, 该技术的实现, 却是他们面临的一大难点和挑战.
对于大部分企业来说, 实现如上功能, 挑战在哪里?
挑战一: 如何做一个自动服务的系统?
是从 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);
- }
- }
- View Code
(三)核心 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/
来源: https://www.cnblogs.com/wangjiming/p/10027439.html