zoukankan      html  css  js  c++  java
  • qurtz.net(转载)

    Quartz+TopShelf实现Windows服务作业调度

     

      Quartz:首先我贴出来了两段代码(下方),可以看出,首先会根据配置文件(quartz.config),包装出一个Quartz.Core.QuartzScheduler

    instance,这是一个调度器,调度各个任务项(Jobs)的执行。这个调度器可以被Start、被Shutdown、被PauseAll、被ResumeAll,这对应

    了windows服务的开启、停止、暂停、恢复。当启动服务,我就调用调度器的Start(),停止服务我就调用调度器的Shutdown()方法。

    复制代码
    namespace QTDemo
    {
        public class ServiceRunner : ServiceControl, ServiceSuspend
        {
            private readonly IScheduler scheduler;
    
            public ServiceRunner()
            {
                scheduler = StdSchedulerFactory.GetDefaultScheduler();
            }
    
            public bool Start(HostControl hostControl)
            {
                scheduler.Start();
                return true;
            }
    复制代码
    复制代码
    // 摘要: 
        //     An implementation of Quartz.ISchedulerFactory that does all of it's work
        //     of creating a Quartz.Core.QuartzScheduler instance based on the contents
        //     of a properties file.
        public class StdSchedulerFactory : ISchedulerFactory
        {
            public const string AutoGenerateInstanceId = "AUTO";
            public const string ConfigurationSectionName = "quartz";
            public const string DefaultInstanceId = "NON_CLUSTERED";
            public const string PropertiesFile = "quartz.config";
    复制代码

      那TopShelf又扮演了什么样的角色呢

      这是一个宿主服务的框架。和ServiceBase、ServiceInstaller那一套的目的一样,都是用来创建Windows服务的。

    项目示例

    1、新建项目控制台应用程序‘QTDemo’

    2、从NuGet安装‘Quartz’,‘Topshelf’,‘Topshelf.Log4Net’ 

    复制代码
    1 <?xml version="1.0" encoding="utf-8"?>
    2 <packages>
    3   <package id="Common.Logging" version="3.3.1" targetFramework="net45" />
    4   <package id="Common.Logging.Core" version="3.3.1" targetFramework="net45" />
    5   <package id="log4net" version="2.0.5" targetFramework="net45" />
    6   <package id="Quartz" version="2.3.3" targetFramework="net45" />
    7   <package id="Topshelf" version="3.3.1" targetFramework="net45" />
    8   <package id="Topshelf.Log4Net" version="3.3.1" targetFramework="net45" />
    9 </packages>
    复制代码

    3、定义一个Job(一个任务项),继承Quartz.IJob

    复制代码
     1 using Quartz;
     2 namespace QTDemo.QuartzJobs
     3 {
     4     public sealed class TestJob : IJob
     5     {
     6         public void Execute(IJobExecutionContext context)
     7         {
     8             CommonHelper.AppLogger.InfoFormat("TestJob测试");
     9 
    10         }
    11     }
    12 }
    13  
    复制代码

    4、配置(新建)quartz.config、quartz_jobs.xml

    quartz.config可直接使用,不用修改

    复制代码
     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 = QuartzTest
     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 = ~/quartz_jobs.xml
    15 
    16 # export this server to remoting context
    17 #quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
    18 #quartz.scheduler.exporter.port = 555
    19 #quartz.scheduler.exporter.bindName = QuartzScheduler
    20 #quartz.scheduler.exporter.channelType = tcp
    21 #quartz.scheduler.exporter.channelName = httpQuartz
    复制代码

    quartz_jobs.xml根据实际的Job项修改

    复制代码
     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <!-- This file contains job definitions in schema version 2.0 format -->
     3 
     4 <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
     5 
     6   <processing-directives>
     7     <overwrite-existing-data>true</overwrite-existing-data>
     8   </processing-directives>
     9 
    10   <schedule>
    11 
    12     <!--TestJob测试 任务配置 -->
    13     <job>
    14       <name>TestJob</name>
    15       <group>Test</group>
    16       <description>TestJob测试</description>
    17       <job-type>QTDemo.QuartzJobs.TestJob,QTDemo</job-type>
    18       <durable>true</durable>
    19       <recover>false</recover>
    20     </job>
    21     <trigger>
    22       <cron>
    23         <name>TestJobTrigger</name>
    24         <group>Test</group>
    25         <job-name>TestJob</job-name>
    26         <job-group>Test</job-group>
    27         <!-- 从start-time起,每5s执行一次IJob.Execute -->
    28         <start-time>2012-01-22T00:00:00+08:00</start-time>
    29         <cron-expression>0/5 * * * * ?</cron-expression>
    30       </cron>
    31     </trigger>
    32     
    33   </schedule>
    34 </job-scheduling-data>
    复制代码

    5、创建服务

    入口:

    复制代码
     1 using System;
     2 using System.IO;
     3 using Topshelf;
     4 
     5 namespace QTDemo
     6 {
     7     class Program
     8     {
     9         static void Main(string[] args)
    10         {
    11             log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
    12 
    16             HostFactory.Run(x =>
    17             {
    18                 x.UseLog4Net();
    19 
    20                 x.Service<ServiceRunner>();
    21 
    22                 x.RunAsLocalSystem();
    23 
    24                 x.SetDescription("Quartz+TopShelf实现Windows服务作业调度的一个示例Demo");
    25                 x.SetDisplayName("QuartzTopShelfDemo服务");
    26                 x.SetServiceName("QuartzTopShelfDemoService");
    27 
    28                 x.EnablePauseAndContinue();
    29 
    30             });
    31         }
    32     }
    33 }
    复制代码

    ServiceRunner.cs

    复制代码
     1 using Quartz;
     2 using Quartz.Impl;
     3 using Topshelf;
     4 
     5 namespace QTDemo
     6 {
     7     public class ServiceRunner : ServiceControl, ServiceSuspend
     8     {
     9         private readonly IScheduler scheduler;
    10 
    11         public ServiceRunner()
    12         {
    13             scheduler = StdSchedulerFactory.GetDefaultScheduler();
    14         }
    15 
    16         public bool Start(HostControl hostControl)
    17         {
    18             scheduler.Start();
    19             return true;
    20         }
    21 
    22         public bool Stop(HostControl hostControl)
    23         {
    24             scheduler.Shutdown(false);
    25             return true;
    26         }
    27 
    28         public bool Continue(HostControl hostControl)
    29         {
    30             scheduler.ResumeAll();
    31             return true;
    32         }
    33 
    34         public bool Pause(HostControl hostControl)
    35         {
    36             scheduler.PauseAll();
    37             return true;
    38         }
    39 
    40     }
    41 }
    复制代码

    log4net配置文件,可直接使用

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <!--日志路径-->
    <param name= "File" value= "Log"/>
    <!--是否是向文件中追加日志-->
    <param name= "AppendToFile" value= "true"/>
    <!--log保留天数-->
    <param name= "MaxSizeRollBackups" value= "10"/>
    <!--日志文件名是否是固定不变的-->
    <param name= "StaticLogFileName" value= "false"/>
    <!--日志文件名格式为:2008-08-31.log-->
    <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
    <!--日志根据日期滚动-->
    <param name= "RollingStyle" value= "Date"/>
    <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%date{HH:mm:ss,fff} %-5p-%m%n" />
    </layout>
    </appender>

    <!-- 控制台前台显示日志 -->
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    <mapping>
    <level value="ERROR" />
    <foreColor value="Red, HighIntensity" />
    </mapping>
    <mapping>
    <level value="Info" />
    <foreColor value="Green" />
    </mapping>
    <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
    </layout>

    <filter type="log4net.Filter.LevelRangeFilter">
    <param name="LevelMin" value="Info" />
    <param name="LevelMax" value="Fatal" />
    </filter>
    </appender>

    <root>
    <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
    <level value="all" />
    <appender-ref ref="ColoredConsoleAppender"/>
    <appender-ref ref="RollingLogFileAppender"/>
    </root>

    </log4net>
    </configuration>

    复制代码
     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <configuration>
     3   <configSections>
     4     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
     5   </configSections>
     6 
     7   <log4net>
     8     <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
     9       <!--日志路径-->
    10       <param name= "File" value= "Log"/>
    11       <!--是否是向文件中追加日志-->
    12       <param name= "AppendToFile" value= "true"/>
    13       <!--log保留天数-->
    14       <param name= "MaxSizeRollBackups" value= "10"/>
    15       <!--日志文件名是否是固定不变的-->
    16       <param name= "StaticLogFileName" value= "false"/>
    17       <!--日志文件名格式为:2008-08-31.log-->
    18       <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
    19       <!--日志根据日期滚动-->
    20       <param name= "RollingStyle" value= "Date"/>
    21       <layout type="log4net.Layout.PatternLayout">
    22         <param name="ConversionPattern" value="%date{HH:mm:ss,fff} %-5p-%m%n" />
    23       </layout>
    24     </appender>
    25 
    26     <!-- 控制台前台显示日志 -->
    27     <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    28       <mapping>
    29         <level value="ERROR" />
    30         <foreColor value="Red, HighIntensity" />
    31       </mapping>
    32       <mapping>
    33         <level value="Info" />
    34         <foreColor value="Green" />
    35       </mapping>
    36       <layout type="log4net.Layout.PatternLayout">
    37         <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
    38       </layout>
    39 
    40       <filter type="log4net.Filter.LevelRangeFilter">
    41         <param name="LevelMin" value="Info" />
    42         <param name="LevelMax" value="Fatal" />
    43       </filter>
    44     </appender>
    45 
    46     <root>
    47       <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
    48       <level value="all" />
    49       <appender-ref ref="ColoredConsoleAppender"/>
    50       <appender-ref ref="RollingLogFileAppender"/>
    51     </root>
    52     
    53   </log4net>
    54 </configuration>
    复制代码

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <!--日志路径-->
    <param name= "File" value= "Log"/>
    <!--是否是向文件中追加日志-->
    <param name= "AppendToFile" value= "true"/>
    <!--log保留天数-->
    <param name= "MaxSizeRollBackups" value= "10"/>
    <!--日志文件名是否是固定不变的-->
    <param name= "StaticLogFileName" value= "false"/>
    <!--日志文件名格式为:2008-08-31.log-->
    <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
    <!--日志根据日期滚动-->
    <param name= "RollingStyle" value= "Date"/>
    <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%date{HH:mm:ss,fff} %-5p-%m%n" />
    </layout>
    </appender>

    <!-- 控制台前台显示日志 -->
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    <mapping>
    <level value="ERROR" />
    <foreColor value="Red, HighIntensity" />
    </mapping>
    <mapping>
    <level value="Info" />
    <foreColor value="Green" />
    </mapping>
    <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
    </layout>

    <filter type="log4net.Filter.LevelRangeFilter">
    <param name="LevelMin" value="Info" />
    <param name="LevelMax" value="Fatal" />
    </filter>
    </appender>

    <root>
    <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
    <level value="all" />
    <appender-ref ref="ColoredConsoleAppender"/>
    <appender-ref ref="RollingLogFileAppender"/>
    </root>

    </log4net>
    </configuration>

    6、quartz.config、quartz_jobs.xml、log4net.config都设置成‘始终复制’

    7、直接F5,调试,发现TestJob每5s执行一次

    8、安装成Windows服务

    用Release编一个版本

    然后用命令行安装服务

    服务面板里可以找到此服务

    启动之,查看日志文件,服务运行正常

    复制代码
    23:23:52,171 INFO -Configuration Result:
    [Success] Name QuartzTopShelfDemoService
    [Success] DisplayName QuartzTopShelfDemo服务
    [Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
    [Success] ServiceName QuartzTopShelfDemoService
    23:23:52,185 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
    23:23:52,194 ERROR-The QuartzTopShelfDemoService service can only be installed as an administrator
    23:25:54,758 INFO -Configuration Result:
    [Success] Name QuartzTopShelfDemoService
    [Success] DisplayName QuartzTopShelfDemo服务
    [Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
    [Success] ServiceName QuartzTopShelfDemoService
    23:25:54,772 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
    23:25:54,781 DEBUG-Attempting to install 'QuartzTopShelfDemoService'
    23:25:54,901 INFO -Installing QuartzTopShelfDemo服务 service
    23:25:55,123 DEBUG-Opening Registry
    23:25:55,123 DEBUG-Service path: "E:DotNetProjectY2016QTDemoQTDemoinReleaseQTDemo.exe"
    23:25:55,123 DEBUG-Image path: "E:DotNetProjectY2016QTDemoQTDemoinReleaseQTDemo.exe"  -displayname "QuartzTopShelfDemo服务" -servicename "QuartzTopShelfDemoService"
    23:25:58,357 DEBUG-Closing Registry
    23:28:10,442 INFO -Configuration Result:
    [Success] Name QuartzTopShelfDemoService
    [Success] DisplayName QuartzTopShelfDemo服务
    [Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
    [Success] ServiceName QuartzTopShelfDemoService
    23:28:10,455 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
    23:28:10,649 DEBUG-Started by the Windows services process
    23:28:10,649 DEBUG-Running as a service, creating service host.
    23:28:10,651 INFO -Starting as a Windows service
    23:28:10,654 DEBUG-[Topshelf] Starting up as a windows service application
    23:28:10,657 INFO -[Topshelf] Starting
    23:28:10,658 DEBUG-[Topshelf] Current Directory: E:DotNetProjectY2016QTDemoQTDemoinRelease
    23:28:10,658 DEBUG-[Topshelf] Arguments: 
    23:28:10,940 INFO -[Topshelf] Started
    23:28:10,988 INFO -TestJob测试
    23:28:15,000 INFO -TestJob测试
    23:28:20,000 INFO -TestJob测试
    复制代码

     源码存网盘 quartz.net

  • 相关阅读:
    java接入钉钉机器人(带源码)
    使用java做一个能赚钱的微信群聊机器人(2020年基于PC端协议最新可用版)
    侠说java8--Stream流操作学习笔记,都在这里了
    Elasticsearch调优篇-慢查询分析笔记
    网络探测和抓包工具 wireshark
    window10远程ubuntu18.04
    springdataJPA mysql myisam innodb
    命令集
    java tmpdir 启动 kafka 命令行
    java jar 启动命令
  • 原文地址:https://www.cnblogs.com/zengpeng/p/9244650.html
Copyright © 2011-2022 走看看