前段时间,花了大量的时间,将原先的计划任务,切换到Quartz.NET来进行管理。原先的后台定时服务都是通过计划任务来实现的,但是随着业务增长,计划任务也越来越多,每个后台服务,都得创建一个计划任务。日常的维护和管理非常麻烦。
于是乎,一咬牙,决定引入Quartz.NET框架,统一都管理全部的后台定时服务。切换过程确实很麻烦。直到今天,才终于有时间整理总结Quartz.NET的相关内容。
Quartz.NET的优点和使用场景,这里不再多说,网上有很多说明,总的来说就是,Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联,配置灵活方便。
参考官方学习文档:http://www.quartz-scheduler.net/documentation/index.html
快速搭建一个Quartz,源代码下载
第一步:新建解决方案和相关项目,并安装相关程序包,如下图所示:
Quartz依赖Common.Logging和Common.Logging.Log4Net,而且Log4Net也是比较熟悉的日志工具,因此我们实际使用中,也是log4net记录日志,另外定时作业一般都是在window服务中,我们也可用Topshelf来创建我们的window服务。
第二步:创建两个Job类Job1,Job2。实现IJob,在Execute方法里编写要处理的业务逻辑,系统就会按照Quartz的配置,定时处理。
using System; using System.Threading; namespace Quartz.Net.Jobs { ////// 实现IJob接口 /// public class Job1 : IJob { private static readonly Common.Logging.ILog logger = Common.Logging.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public void Execute(IJobExecutionContext context) { try { logger.Info("Job1 任务运行开始"); for (int i = 0; i < 5; i++) { Thread.Sleep(100); logger.InfoFormat("Job1 正在运行{0}", i); } logger.Info("Job1任务运行结束"); } catch (Exception ex) { logger.Error("Job1 运行异常", ex); } } } }
第三步:配置quartz.config、quartz_jobs.xml
Quartz 实例的基础配置:quartz.config
# You can configure your scheduler in eitherconfiguration 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
各个Job 任务的配置 :quartz_jobs.xml
"1.0" encoding="UTF-8"?>"http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0"> true Job1 JobGroup Quartz Job1 Quartz.Net.Jobs.Job1,Quartz.Net.Jobs true false Job2 JobGroup Quartz Job2 Quartz.Net.Jobs.Job2,Quartz.Net.Jobs true false Job1Trigger JobTriggerGroup Job1 JobGroup 0/30 * * * * ? Job2Trigger1 JobTriggerGroup Job2 JobGroup 0 * * * * ?
第四步:宿主程序,可以是window服务,也可以是后台Console程序,如何用Topshelf来创建我们的window服务,请看另外一篇文章《使用Topshelf 开发windows服务》。
namespace Quartz.Net.Console { class Program { private static IScheduler scheduler; static void Main(string[] args) { ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); scheduler = schedulerFactory.GetScheduler(); scheduler.Start(); } } }
注意:quartz_jobs.xml和quartz.config这两个文件,要手动复制到输出目录下,或者在vs中,分别选中这两个文件→右键属性→复制到输入目录设为:始终复制。
否则读取不到这两个配置文件,程序无法运行。
运行后,效果如下图: