Quartz总结

Quartz.NET 入门

概述

Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。
整合了 Quartz.NET的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。

快速搭建一个Quartz

第一步:安装
Install-Package Quartz
Install-Package Common.Logging.Log4Net1211
Install-Package log4net
Install-Package Topshelf
Install-Package Topshelf.Log4Net

Quartz依赖Common.Logging和Common.Logging.Log4Net1211,又因为Log4Net是比较标准的日志工具,因此我们一般都会安装log4net,
另外定时作业一般都允许在后台服务中,因此我们也安装了Topshelf。

第二步:实现IJob

TestJob.cs 实现IJob,在Execute方法里编写要处理的业务逻辑,系统就会按照Quartz的配置,定时处理。

using log4net;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuartzDemo.QuartzJobs
{
    public sealed class TestJob : IJob
    {
        private readonly ILog _logger = LogManager.GetLogger(typeof(TestJob));

        public void Execute(IJobExecutionContext context)
        {
            _logger.InfoFormat("TestJob测试");
        }
    }
}
第三步:使用Topshelf调度任务
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf;

namespace QuartzDemo
{
    public sealed class ServiceRunner : ServiceControl, ServiceSuspend
    {
        private readonly IScheduler scheduler;

        public ServiceRunner()
        {
            scheduler = StdSchedulerFactory.GetDefaultScheduler();
        }

        public bool Start(HostControl hostControl)
        {
            scheduler.Start();
            return true;
        }

        public bool Stop(HostControl hostControl)
        {
            scheduler.Shutdown(false);
            return true;
        }

        public bool Continue(HostControl hostControl)
        {
            scheduler.ResumeAll();
            return true;
        }

        public bool Pause(HostControl hostControl)
        {
            scheduler.PauseAll();
            return true;
        }
    }
}
第四步:程序入口
namespace QuartzDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
            HostFactory.Run(x =>
            {
                x.UseLog4Net();

                x.Service();

                x.SetDescription("QuartzDemo服务描述");
                x.SetDisplayName("QuartzDemo服务显示名称");
                x.SetServiceName("QuartzDemo服务名称");

                x.EnablePauseAndContinue();
            });
        }
    }
}
第五步:配置quartz.config、quartz_jobs.xml、log4net.config
quartz.config

因格式原因在#前加了/,使用时去掉即可

    /# You can configure your scheduler in either  configuration section
    /# or in quartz properties file
    /# Configuration section has precedence

    quartz.scheduler.instanceName = QuartzTest

    /# configure thread pool info
    quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
    quartz.threadPool.threadCount = 10
    quartz.threadPool.threadPriority = Normal

    /# job initialization plugin handles our xml reading, without it defaults are used
    quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
    quartz.plugin.xml.fileNames = ~/quartz_jobs.xml

    /# export this server to remoting context
    /#quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
    /#quartz.scheduler.exporter.port = 555
    /#quartz.scheduler.exporter.bindName = QuartzScheduler
    /#quartz.scheduler.exporter.channelType = tcp
    /#quartz.scheduler.exporter.channelName = httpQuartz
    
quartz_jobs.xml

  
    true
  
  
    
    
      
      SimpleJob
      
      sampleGroup
      
      Sample job for Quartz Server
      
      WindowsService.Job.SimpleJob, WindowsService
      true
      false
    
    
    
      
      
      
        JobTrigger
        JobTriggers
        cron trigger
        SimpleJob
        sampleGroup
        
        0/2 * * * * ?
      
    
  
job 任务:用来定义每个具体的任务的,多个任务请创建多个job节点即可

    + name(必填) 任务名称,同一个group中多个job的name不能相同,若未设置group则所有未设置group的job为同一个分组
    + group(选填) 任务所属分组,用于标识任务所属分组
    + description(选填) 任务描述,用于描述任务具体内容
    + job-type(必填) 任务类型,任务的具体类型及所属程序集,格式:实现了IJob接口的包含完整命名空间的类名,程序集名称
    + durable(选填) 具体作用不知,官方示例中默认为true
    + recover(选填) 具体作用不知,官方示例中默认为false

trigger 任务触发器:用于定义使用何种方式出发任务(job),同一个job可以定义多个trigger ,多个trigger 各自独立的执行调度,
        每个trigger 中必须且只能定义一种触发器类型(calendar-interval、simple、cron)
    + simple 简单任务的触发器类型,可以调度用于重复执行的任务
        * name(必填) 触发器名称,同一个分组中的名称必须不同
        * group(选填) 触发器组
        * description(选填) 触发器描述
        * job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同
        * job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同
        * start-time(选填) 任务开始执行时间utc时间,北京时间需要+08:00,
                如:2012-04-01T08:00:00+08:00表示北京时间2012年4月1日上午8:00开始执行,
                注意服务启动或重启时都会检测此属性,若没有设置此属性或者start-time设置的时间比当前时间较早,
                则服务启动后会立即执行一次调度,若设置的时间比当前时间晚,服务会等到设置时间相同后才会第一次执行任务,一般若无特殊需要请不要设置此属性
        * repeat-count(必填)  任务执行次数,如:-1表示无限次执行,10表示执行10次
        * repeat-interval(必填) 任务触发间隔(毫秒),如:10000 每10秒执行一次
    + cron:复杂任务触发器--使用cron表达式定制任务调度
        * name(必填) 触发器名称,同一个分组中的名称必须不同
        * group(选填) 触发器组
        * escription(选填) 触发器描述
        * job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同
        * job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同
        * start-time(选填) 任务开始执行时间utc时间,北京时间需要+08:00,
                如:2012-04-01T08:00:00+08:00表示北京时间2012年4月1日上午8:00开始执行,
                注意服务启动或重启时都会检测此属性,若没有设置此属性,服务会根据cron-expression的设置执行任务调度;若start-time设置的时间比当前时间较早,则服务启动后会忽略掉cron-expression设置,立即执行一次调度,之后再根据cron-expression执行任务调度;若设置的时间比当前时间晚,则服务会在到达设置时间相同后才会应用cron-expression,
                根据规则执行任务调度,一般若无特殊需要请不要设置此属性
        * cron-expression(必填) cron表达式,如:0/10 * * * * ?每10秒执行一次
log4net.config


  
    

Quartz任务调度

泛型数组批量job(可用数据库)+服务日志+log4net打印日志+制作windows服务

安装

Install-Package Quartz(2.6.2)
Install-Package Common.Logging.Log4Net1211(3.0)
Install-Package Topshelf(3.2)
Install-Package Topshelf.Log4Net(3.2)

配置文件


    
      

相关Job类

JobInfo对象(任务信息),JobType类型

任务信息:名称、触发器、群组、类型(根据不同的类型执行不同的Job内容

public class JobInfo
    {
        public JobInfo(string jobName, string group, string trigger, JobType jobType)
        {
            if (jobName == null || trigger == null || group == null)
            {
                throw new ArgumentNullException("jobName");
            }
            this.JobName = jobName;
            this.Trigger = trigger;
            this.Group = group;
            this.JobType = jobType;
        }

        /// 
        /// 名称
        /// 
        public string JobName { get; set; }

        /// 
        /// Job的触发器  cron表达式
        /// 
        public string Trigger { get; set; }

        /// 
        /// 群组
        /// 
        public string Group { get; set; }

        /// 
        /// Job类型
        /// 
        public JobType JobType { get; set; }
    }

    /// 
    /// Job类型枚举
    /// 
    public enum JobType
    {
        /// 
        /// 任务1
        /// 
        Job1 = 1,
        /// 
        /// 任务2
        /// 
        Job2 = 2
    }
JobInfoList任务集合

模拟的任务集合,实际应用中可固定,可从数据库中获取

public class JobInfoList
{
    /// 
    /// 脚本服务组
    /// 
    public static List JobList_ZhongShanHos = new List
    {
        new JobInfo("任务1", "测试脚本", "*/5 * * * * ?", JobType.Job1),
        new JobInfo("任务2", "测试脚本", "*/7 * * * * ?", JobType.Job2)
    };
}
Job内容

配置具体的Job内容与需要输出的自定义日志,这里的日志使用log4net作为记录

using System;
using Quartz;

namespace T5.Jobs
{
    public class TestJob : IJob
    {
        private static readonly log4net.ILog LogInfo = log4net.LogManager.GetLogger("LogCustomEx");
        private static readonly log4net.ILog LogError = log4net.LogManager.GetLogger("LogError");

        public void Execute(IJobExecutionContext context)
        {
            var map = context.JobDetail.JobDataMap;
            var jobInfo = map["KEY"] as JobInfo;
            if (jobInfo == null) { return; }

            //记录日志
            LogInfo.Info("\n【服务已启动】" + "\n【启动组】:" + jobInfo.Group + "\n【启动名称】:" + jobInfo.JobName + "\n【启动时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            try
            {
                switch (jobInfo.JobType)
                {
                    //基础信息
                    case JobType.Job1: LogInfo.Info("这是任务1"); break;
                    case JobType.Job2: LogInfo.Info("这是任务2"); break;

                    default: break;
                }
            }
            catch (Exception ex)
            {
                //记录日志
                LogError.Error("\n【服务执行出错】" +
                              "\n【启动组】:" + jobInfo.Group +
                              "\n【启动名称】:" + jobInfo.JobName +
                              "\n【时间】:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +
                              "\n【错误信息】:" + ex.Message);
                return;
            }
        }
    }

}
配置Job执行方法
using System.Collections.Generic;
using Quartz;
using Quartz.Impl;
using T5.Jobs;
using Topshelf;

namespace T5
{
    public sealed class ServerRunner : ServiceControl, ServiceSuspend
    {
        private readonly IScheduler scheduler;

        public ServerRunner()
        {
            scheduler = StdSchedulerFactory.GetDefaultScheduler();
        }

        public bool Start(HostControl hostControl)
        {
            var jobList = new List();

            //配置JobList任务
            jobList.AddRange(JobInfoList.JobList_ZhongShanHos);

            jobList.ForEach(
                x =>
                {
                    var dic = new Dictionary { { "KEY", x } };
                    var map = new JobDataMap(dic);
                    var job =
                        JobBuilder.Create()
                            .WithIdentity(x.JobName, x.Group)
                            .UsingJobData(map)
                            .RequestRecovery()
                            .Build();
                    var trigger =
                        TriggerBuilder.Create()
                            .WithIdentity(x.JobName, x.Group)
                            .WithCronSchedule(x.Trigger)
                            .Build();
                    scheduler.ScheduleJob(job, trigger);
                });
            scheduler.Start();
            return true;
        }

        public bool Stop(HostControl hostControl)
        {
            scheduler.Shutdown(false);
            return true;
        }

        public bool Continue(HostControl hostControl)
        {
            scheduler.ResumeAll();
            return true;
        }

        public bool Pause(HostControl hostControl)
        {
            scheduler.PauseAll();
            return true;
        }
    }
}
配置入口文件
using Topshelf;

namespace T5
{
    class Program
    {
        static void Main(string[] args)
        {
            //配置Log4日志
            log4net.Config.XmlConfigurator.Configure();

            //Windows服务
            HostFactory.Run(x =>
            {
                x.UseLog4Net();

                x.Service();

                x.SetDescription("Quartz日志记录服务");
                x.SetDisplayName("Quartz");
                x.SetServiceName("QuartzLog");

                x.EnablePauseAndContinue();
            });
        }
    }
}

你可能感兴趣的:(Quartz总结)