zoukankan      html  css  js  c++  java
  • 浅谈Quartz定时任务调度

    一  开发概述

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

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

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

          是从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/

    五  版权区

    • 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
    • 博主网址:http://www.cnblogs.com/wangjiming/。
    • 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
    • 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。
    • 可以转载该博客,但必须著名博客来源。
  • 相关阅读:
    HTTP Status 500
    HTTP Status 500
    HTTP Status 500
    测试错误ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.问题的解决
    页面报错误:HTTP Status 500
    eclipse怎么设置在新建JSP文件的编码为UTF-8?
    linux 开启oracle监听
    linux 修改环境变量
    linux 修改oracle的字符集
    Cannot change version of project facet Dynamic Web Module to 2.5
  • 原文地址:https://www.cnblogs.com/wangjiming/p/10027439.html
Copyright © 2011-2022 走看看