• Quartz.NET Windows 服务示例


          想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度引入进来了,那今天就简单的介绍一下 Quartz.NET 基于 Windows 服务宿主是怎样配置使用的。

    Quartz.NET 是一个优秀的任务调度框架,移植于 Java 版的 Quartz 。

    官网:http://www.quartz-scheduler.net

    Github:https://github.com/quartznet/quartznet

    示例环境

    - .Net 4.5.2

    - Quartz 2.4.1

    - Common.Logging 3.3.1

    - log4net 2.0.5

    - Common.Logging.Log4Net1213 3.3.1

    源码地址:https://github.com/Wlitsoft/QuartzNETWinServiceSample

    配置

    1. quartz.config

    这个配置文件需要放在服务运行根目录下,用于指定 quartz 的一些运行配置,比如调度名称、线程池实现组件、线程池大小、任务配置文件路径等。

     1 # You can configure your scheduler in either <quartz> configuration section
     2 # or in quartz properties file
     3 # Configuration section has precedence
     4 
     5 quartz.scheduler.instanceName = QuartzNETWinServiceScheduler
     6 
     7 # configure thread pool info
     8 quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
     9 quartz.threadPool.threadCount = 10
    10 quartz.threadPool.threadPriority = Normal
    11 
    12 # job initialization plugin handles our xml reading, without it defaults are used
    13 quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
    14 quartz.plugin.xml.fileNames = ~/Conf/jobs.config

    暂时需求需要修改的只有一处,看最后一行 quartz.plugin.xml.fileNames = ~/Conf/jobs.config 指定任务的配置文件路径。

    2. 任务配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!-- This file contains job definitions in schema version 2.0 format -->
     3 <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
     4 
     5   <processing-directives>
     6     <overwrite-existing-data>true</overwrite-existing-data>
     7   </processing-directives>
     8 
     9   <schedule>
    10     <job>
    11       <name>Job1</name>
    12       <group>Jobs</group>
    13       <description>任务1</description>
    14       <job-type>Wlitsoft.ProjectSample.QuartzNETWinService.Job.Job1,QuartzNETWinService</job-type>
    15       <durable>true</durable>
    16       <recover>false</recover>
    17     </job>
    18     <trigger>
    19       <simple>
    20         <name>Job1Trigger</name>
    21         <group>Jobs</group>
    22         <description>每 30 秒执行一次</description>
    23         <job-name>Job1</job-name>
    24         <job-group>Jobs</job-group>
    25         <repeat-count>-1</repeat-count>
    26         <repeat-interval>30000</repeat-interval>
    27       </simple>
    28     </trigger>
    29   </schedule>
    30 </job-scheduling-data>

    以下为配置文件属性:

     - 任务 (job 节点)

    job 节点项说明
    名称 类型 是否必填 默认值 描述
    name string Y   任务名称
    group string N 默认组名 任务组名称
    description string N   任务描述
    job-type string Y   任务的类型全名称,一般实现 IJob 接口
    durable boolean N false 任务完成后是否依然保存到数据库
    recover boolean N false 应用或服务重启之后是否忽略过期任务

      

     

    - 触发器 (trigger 节点)

    下面说下最常用的两种触发器:

    1)简单触发器(simple 节点)用于触发定时轮训执行的任务。

    simple 节点项说明
    名称 类型 是否必填 默认值 描述
    name string Y   触发器名称
    group string N 默认组名 触发器名称
    description string N   触发器描述
    job-name string Y   要触发的任务的名称
    job-group string Y   要触发的任务的组名称
    repeat-count int Y 0 重复次数(0:不执行;-1:不限次数)
    repeat-interval long Y 0 间隔时间(单位:毫秒)
    start-time date N 当前时间 开始时间
    end-time date N   结束时间(如果不指定则一直执行直到重复次数)

    2)Cron 触发器(cron 节点)根据 cron 表达式触发任务。

    cron 节点项说明
    名称 类型 是否必填 默认值 描述
    name string Y   触发器名称
    group string N 默认组名 触发器名称
    description string N   触发器描述
    job-name string Y   要触发的任务的名称
    job-group string Y   要触发的任务的组名称
    cron string Y   规则表达式
    start-time date N 当前时间 开始时间
    end-time date N   结束时间

    注:cron 表达式在线生成:http://cron.qqe2.com

    3. 日志配置文件

    1) app.config

    - configSctions 

    1 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    2 <sectionGroup name="common">
    3       <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    4 </sectionGroup>

    - commong.logging 配置

    1 <common>
    2     <logging>
    3       <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1213">
    4         <arg key="configType" value="FILE-WATCH" />
    5         <arg key="configFile" value="~/Conf/log4net.config" />
    6         <arg key="level" value="INFO" />
    7       </factoryAdapter>
    8     </logging>
    9 </common>

        - configType : 用于指定日子配置文件类型,取值:INLINE - 在当前配置文件总;FILE-WATCH - 配置文件中。

        - configFile:配置文件路径。

        - level:日子输出级别。

    - log4net 配置

     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <configuration>
     3   <configSections>
     4     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
     5   </configSections>
     6   <log4net>
     7 
     8     <logger name="job1" additivity="false" >
     9       <level value="ALL" />
    10       <appender-ref ref="Job1TxtAppender" />
    11     </logger>
    12 
    13     <appender name="Job1TxtAppender" type="log4net.Appender.RollingFileAppender">
    14       <file value="log/job1.txt" />
    15       <appendToFile value="true" />
    16       <param name="MaxSizeRollBackups" value="10"/>
    17       <param name="MaximumFileSize" value="10240KB"/>
    18       <param name="RollingStyle" value="Size"/>
    19       <param name="StaticLogFileName" value="true"/>
    20       <layout type="log4net.Layout.PatternLayout">
    21         <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    22       </layout>
    23     </appender>
    24     
    25     <appender name="InfoFileAppender" type="log4net.Appender.RollingFileAppender">
    26       <file value="log/" />
    27       <appendToFile value="true" />
    28       <param name="DatePattern" value="yyyy-MM-dd'.txt'" />
    29       <rollingStyle value="Date" />
    30       <maxSizeRollBackups value="100" />
    31       <maximumFileSize value="1024KB" />
    32       <staticLogFileName value="false" />
    33       <Encoding value="UTF-8" />
    34       <filter type="log4net.Filter.LevelRangeFilter">
    35         <param name="LevelMin" value="INFO" />
    36         <param name="LevelMax" value="INFO" />
    37       </filter>
    38       <layout type="log4net.Layout.PatternLayout">
    39         <conversionPattern value="%date %-5level %logger  - %message%newline" />
    40       </layout>
    41     </appender>
    42     <appender name="ErrorFileAppender" type="log4net.Appender.RollingFileAppender">
    43       <file value="log/error.txt" />
    44       <appendToFile value="true" />
    45       <rollingStyle value="Size" />
    46       <maxSizeRollBackups value="100" />
    47       <maximumFileSize value="10240KB" />
    48       <staticLogFileName value="true" />
    49       <Encoding value="UTF-8" />
    50       <filter type="log4net.Filter.LevelRangeFilter">
    51         <param name="LevelMin" value="WARN" />
    52         <param name="LevelMax" value="FATAL" />
    53       </filter>
    54       <layout type="log4net.Layout.PatternLayout">
    55         <conversionPattern value="%date %-5level %logger - %message%newline" />
    56       </layout>
    57     </appender>
    58     <root>
    59       <level value="INFO" />
    60       <appender-ref ref="InfoFileAppender" />
    61       <appender-ref ref="ErrorFileAppender" />
    62     </root>
    63   </log4net>
    64 
    65 </configuration>
    log4net.config

    主程序代码:

     1 using System.ServiceProcess;
     2 using Common.Logging;
     3 using Quartz;
     4 using Quartz.Impl;
     5 
     6 namespace Wlitsoft.ProjectSample.QuartzNETWinService
     7 {
     8     public partial class MainService : ServiceBase
     9     {
    10         #region 私有属性
    11 
    12         //日志记录这。
    13         private readonly ILog _logger;
    14 
    15         //调度器。
    16         private readonly IScheduler _scheduler;
    17 
    18         #endregion
    19 
    20         #region 构造方法
    21 
    22         /// <summary>
    23         /// 初始化 <see cref="MainService"/> 类的新实例。
    24         /// </summary>
    25         public MainService()
    26         {
    27             InitializeComponent();
    28             this._logger = LogManager.GetLogger(this.GetType());
    29             StdSchedulerFactory factory = new StdSchedulerFactory();
    30             this._scheduler = factory.GetScheduler();
    31         }
    32 
    33         #endregion
    34 
    35         protected override void OnStart(string[] args)
    36         {
    37             this._scheduler.Start();
    38             this._logger.Info("服务启动");
    39         }
    40 
    41         protected override void OnStop()
    42         {
    43             if (!this._scheduler.IsShutdown)
    44                 this._scheduler.Shutdown();
    45             this._logger.Info("服务停止");
    46         }
    47 
    48         protected override void OnPause()
    49         {
    50             this._scheduler.PauseAll();
    51             base.OnPause();
    52         }
    53 
    54         protected override void OnContinue()
    55         {
    56             this._scheduler.ResumeAll();
    57             base.OnContinue();
    58         }
    59     }
    60 }

    示例任务代码:

     1 using Common.Logging;
     2 using Quartz;
     3 
     4 namespace Wlitsoft.ProjectSample.QuartzNETWinService.Job
     5 {
     6     public class Job1 : IJob
     7     {
     8         //日志构造者。
     9         private static readonly ILog Logger = LogManager.GetLogger("job1");
    10 
    11         #region Implementation of IJob
    12 
    13         /// <summary>
    14         /// Called by the <see cref="T:Quartz.IScheduler" /> when a <see cref="T:Quartz.ITrigger" />
    15         /// fires that is associated with the <see cref="T:Quartz.IJob" />.
    16         /// </summary>
    17         /// <remarks>
    18         /// The implementation may wish to set a  result object on the
    19         /// JobExecutionContext before this method exits.  The result itself
    20         /// is meaningless to Quartz, but may be informative to
    21         /// <see cref="T:Quartz.IJobListener" />s or
    22         /// <see cref="T:Quartz.ITriggerListener" />s that are watching the job's
    23         /// execution.
    24         /// </remarks>
    25         /// <param name="context">The execution context.</param>
    26         public void Execute(IJobExecutionContext context)
    27         {
    28             string jobDes = context.JobDetail.Description;
    29             Logger.Info($"{jobDes}运行");
    30         }
    31 
    32         #endregion
    33     }
    34 }

    源码地址:https://github.com/Wlitsoft/QuartzNETWinServiceSample 

    推荐阅读:一个技术汪的开源梦

  • 相关阅读:
    云小课 | 华为云KYON之VPC终端节点
    华为云专家向宇:工欲善其事必先利其器,才能做数据的“管家”
    NB-IoT四大关键特性及实现告诉你,为啥NB
    Base64 原理
    netty系列之:轻轻松松搭个支持中文的服务器
    轻松让你的nginx服务器支持HTTP2协议
    是的你没看错,HTTP3来了
    HTTP协议之:HTTP/1.1和HTTP/2
    netty系列之:在netty中使用protobuf协议
    protocol buffer的高效编码方式
  • 原文地址:https://www.cnblogs.com/wlitsoft/p/QuartzNET-Windows-Service-Sample.html
Copyright © 2020-2023  润新知