一  开发概述

对于具有一定规模的大多数企业来说,存在着这样一种需求:存在某个或某些任务,需要系统定期,自动地执行,然而,对大多数企业来说,该技术的实现,却是他们面临的一大难点和挑战。

 对于大部分企业来说,实现如上功能,挑战在哪里?

挑战一:如何做一个自动服务的系统?

是从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。
  • 可以转载该博客,但必须著名博客来源。

浅谈Quartz定时任务调度的更多相关文章

  1. 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出

    1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法   Shiro框架内部整合好缓存管理器, ...

  2. quartz 定时任务调度管理器

    本项目使用的是spring-quartz 以下配置可以开启多个已知定时任务 <?xml version="1.0" encoding="UTF-8"?&g ...

  3. 浅谈Quartz.Net 从无到有创建实例

    一.Quartz.Net介绍 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或 ...

  4. Quartz 定时任务调度

    一.在Quartz.NET中quartz.properties的配置文件,忽略不修改,考虑下面: var props = new NameValueCollection { { "quart ...

  5. 浅谈Quartz(SimpleTrigger&CronTrigger)

    private void quartzOrderReturn(List<String> returnIds) { try { Scheduler scheduler = StdSchedu ...

  6. 分布式定时任务调度系统技术解决方案(xxl-job、Elastic-job、Saturn)

    1.业务场景 保险人管系统每月工资结算,平安有150万代理人,如何快速的进行工资结算(数据运算型) 保险短信开门红/电商双十一 1000w+短信发送(短时汇聚型) 工作中业务场景非常多,所涉及到的场景 ...

  7. 浅谈Spring中的Quartz配置

    浅谈Spring中的Quartz配置 2009-06-26 14:04 樊凯 博客园 字号:T | T Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在 ...

  8. 一文揭秘定时任务调度框架quartz

    之前写过quartz或者引用过quartz的一些文章,有很多人给我发消息问quartz的相关问题, quartz 报错:java.lang.classNotFoundException quartz源 ...

  9. Hosted Services+Quartz实现定时任务调度

    背景 之前.net core使用quartz.net时,总感觉非常变扭,百度和谷歌了N久都没解决以下问题,造成代码丑陋,非常不优雅: 1.项目启动时,要立刻恢复执行quartz.net中的任务 2.q ...

随机推荐

  1. Unity3D中AssetBundle应用

    工程中的模型等资源转化为Prefab后,打包成AssetBundle,可以大幅降低资源的空间占有度,并且提高资源加载的效率. 一.AssetBundle的打包 先看下打包Prefab的脚本代码,这段脚 ...

  2. Java List中迭代器遍历

    在java中,List接口从Collection接口中继承了 iterator()函数,返回值是一个T类型的迭代器(泛型),T是List中元素的类型 public class TestListAndI ...

  3. How Does Closure Work in Javascript?

    Simply, closure is the scope that it can visite and operate the variables outside of the function wh ...

  4. python 类成员知识点学习的一个坑(初学者,大神请绕行)

    先来段小程序class Foo: name = "abc" def __init__(self,age): self.age = age print(Foo.name)Foo.na ...

  5. ICO图标下载地址

    http://findicons.com/ http://www.iconfont.cn/

  6. Jenkins关闭和重启实现方式.

    1.关闭Jenkins 只需要在访问jenkins服务器的网址url地址后加上exit.例如我jenkins的地址http://localhost:8080/,那么我只需要在浏览器地址栏上敲下http ...

  7. map put值 使用匿名函数

    List<Map<String, Object>> list = setRoleMenuRlMapper.selectMapByParams(params); // Map m ...

  8. Android逆向之静态分析

    想必打过CTF的小伙伴多多少少都触过Android逆向,所以斗哥将给大家整一期关于Android逆向的静态分析与动态分析.本期先带来Android逆向的静态分析,包括逆向工具使用.文件说明.例题解析等 ...

  9. 吴恩达机器学习笔记21-正则化线性回归(Regularized Linear Regression)

    对于线性回归的求解,我们之前推导了两种学习算法:一种基于梯度下降,一种基于正规方程. 正则化线性回归的代价函数为: 如果我们要使用梯度下降法令这个代价函数最小化,因为我们未对theta0进行正则化,所 ...

  10. Redis 设计与实现 (一)--数据结构

    底层数据结构:动态字符串.字典.整数集合.双端链表.压缩列表 字符串对象: int    浮点数值 raw  字符串值>32字节 embstr   字符串值<32字节 字符串编码转换: i ...