Net作业调度-----Quartz.Net

一:业务需求:

项目需要在不同时刻,执行一个或很多个不同的作业。

Windows执行计划这时并不能很好的满足需求了,迫切需要一个更为强大,方便管理,集群部署的作业调度框架。

二:介绍

Quartz一个开源的作业调度框架,OpenSymphony的开源项目。Quartz.Net 是Quartz的C#移植版本。

特性:

1:支持集群,作业分组,作业远程管理。 

2:自定义精细的时间触发器,使用简单,作业和触发分离。

3:数据库支持,可以寄宿Windows服务,WebSite,winform等。

三:使用的方法:

    1.名词的解释:

       Scheduler     作业调度器。

   IJob             作业接口,继承并实现Execute, 编写执行的具体作业逻辑。

  JobBuilder       根据设置,生成一个详细作业信息(JobDetail)。

  TriggerBuilder   根据规则,生产对应的Trigger

2.学习的官网

    Quartz.Net官方2.X教程  http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/index.html

    Quartz.Net开源地址   https://github.com/quartznet/quartznet

3.Nuget安装

 PM> Install-Package Quartz 

 4.代码解释:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Quartz;
using Quartz.Impl;
using System.Collections.Specialized;

namespace Portal.JobScheduler
{
    public class QuartzManager<T> where T:class,IJob
    {
        //调度程序的工厂的接口中 实例一个具体的调度方法
        private static ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //JOb群组名
        private static string JOB_GROUP_NAME = "JOBGROUP_NAME";
        //触发器群
        private static string TRIGGER_GROUP_NAME = "TRIGGERGROUP_NAME";

       


        /// <summary>
        /// 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 
        /// </summary>
        /// <param name="pStrJobName">任务名</param>
        /// <param name="pStrCronExpress">触发器表达式</param>
        public static void AddJob(string pStrJobName, string pStrCronExpress)
        {
            try
            {
                //接口中获取调度工厂的  GetScheduler()  方法
                IScheduler sched = schedulerFactory.GetScheduler();
                //创建任务
                IJobDetail job = JobBuilder.Create<T>().WithIdentity(pStrJobName, JOB_GROUP_NAME).Build();
                //创建触发器
                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity(pStrJobName, TRIGGER_GROUP_NAME)
                    .WithCronSchedule(pStrCronExpress)
                    .Build();

                sched.ScheduleJob(job, trigger);
                sched.Start();
            }
            catch (Exception e)
            {
                
                throw new Exception(e.Message);
            }
        }


        /// <summary>
        /// 移除一个任务(使用默认的任务组名,触发器名,触发器组名) 
        /// </summary>
        /// <param name="pStrJobName"></param>
        public static void RemoveJob(string pStrJobName)
        {
            try
            {
                 IScheduler sched = schedulerFactory.GetScheduler();
                 JobKey jobkey = new JobKey(pStrJobName);
                 TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME);

                 //停止触发器
                 sched.PauseTrigger(triggerKey);
                //移除触发器
                 sched.UnscheduleJob(triggerKey);
                //删除任务
                 sched.DeleteJob(jobkey);
            }
            catch (Exception e)
            { 
                throw new Exception(e.Message);
            }
        }


        /// <summary>
        /// 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) 
        /// </summary>
        /// <param name="pStrJobName">任务名</param>
        /// <param name="pStrCronExpress">触发器表达式</param>
        public static void ModifyJobTime(string pStrJobName, string pStrCronExpress, IDictionary<string, object> pDictionary)
        {
            try
            {
                IScheduler sched = schedulerFactory.GetScheduler();
                TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME);
                ICronTrigger trigger = (ICronTrigger)sched.GetTrigger(triggerKey);
                if (trigger == null)
                {
                    return;
                }
                RemoveJob(pStrJobName);
                AddJob(pStrJobName, pStrCronExpress);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }


         /// <summary>
         ///  开启所有定时任务
         /// </summary>
        public static void startJobs()
        {
            try
            {
                IScheduler sched = schedulerFactory.GetScheduler();
                sched.Start();
            }
            catch (Exception e)
            {
                
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 关闭所有的定时任务
        /// </summary>
        public static void shutdownJobs()
        {
            try
            {
                IScheduler sched = schedulerFactory.GetScheduler();
                if (!sched.IsShutdown)
                {
                    sched.Shutdown();
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 恢复所有的任务
        /// </summary>
        public static void ResumeAllJobs()
        {
            try
            {
                   IScheduler sched = schedulerFactory.GetScheduler();
                   if (!sched.IsShutdown)
                   {
                       sched.ResumeAll();
                   }
            }
            catch (Exception e)
            {
                
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 暂停所有的作业
        /// </summary>
        public static void PauseAllJobs()
        {
            try
            {
                  IScheduler sched = schedulerFactory.GetScheduler();
                  sched.PauseAll();
            }
            catch (Exception e)
            {
                
                throw new Exception(e.Message);
            }
        }
    }
}

 Asp。net调用:

在global文件中进行配置

 private void RegisterJob()
        {
            QuartzManager<SHiddenDangerCaution>.AddJob("SHiddenDangerCautionInfo", "0 0 08 ? * *");

        }

  调度类的写法:

public class SyncWeatherInfoJob:IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            UpdateWeatherForecast();
        }
        /// <summary>
        /// 更新气象实况信息
        /// </summary>
        public void UpdateWeatherForecast()
        {
            WeatherForecast.InsertWeatherInfo();   --这里的代码就不贴出来
        }
    }

 这样就完成了调度任务

 

CrystalQuartz 远程管理

CrystalQuartz开源的地址   https://github.com/guryanovev/CrystalQuartz

但如果想方便的知道某个作业执行情况,需要暂停,启动等操作行为,这时候就需要个Job管理的界面。

接下来介绍Quartz.NET如何进行远程job管理,如图:

代码:

  一:作业服务端

static void Main(string[] args)
       {
           var properties = new NameValueCollection();
           properties["quartz.scheduler.instanceName"] = "RemoteServerSchedulerClient";
 
           // 设置线程池
           properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
           properties["quartz.threadPool.threadCount"] = "5";
           properties["quartz.threadPool.threadPriority"] = "Normal";
 
           // 远程输出配置
           properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
           properties["quartz.scheduler.exporter.port"] = "556";
           properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
           properties["quartz.scheduler.exporter.channelType"] = "tcp";
 
           var schedulerFactory = new StdSchedulerFactory(properties);
           var scheduler = schedulerFactory.GetScheduler();
 
           var job = JobBuilder.Create<PrintMessageJob>()
               .WithIdentity("myJob", "group1")
               .Build();
 
           var trigger = TriggerBuilder.Create()
               .WithIdentity("myJobTrigger", "group1")
               .StartNow()
               .WithCronSchedule("/10 * * ? * *")
               .Build();
           scheduler.ScheduleJob(job, trigger);
           scheduler.Start();
 
       }

public class PrintMessageJob : IJob
   {
       public void Execute(IJobExecutionContext context)
       {
           Console.WriteLine("Hello!");
       }
   }

 

二:作业远程管理端,无需写任何代码,引用官方程序集,嵌入到已有的web网站。

   PM> Install-Package CrystalQuartz.Remote

 

      Webconfig 需要配置的地方

<configuration> 
    <crystalQuartz>
        <provider>
            <add property="Type" value="CrystalQuartz.Core.SchedulerProviders.RemoteSchedulerProvider, CrystalQuartz.Core" />
            <add property="SchedulerHost" value="tcp://127.0.0.1:556/QuartzScheduler" /> <!--TCP监听的地址-->
        </provider>
 
    </crystalQuartz>
<system.webServer>
      <!-- Handler拦截处理了,输出作业监控页面-->
        <handlers>
            <add name="CrystalQuartzPanel" verb="*" path="CrystalQuartzPanel.axd" type="CrystalQuartz.Web.PagesHandler, CrystalQuartz.Web" />
        </handlers>
    </system.webServer>
</configuration>

 

 

posted @ 2016-09-29 19:37  石shi  阅读(1404)  评论(1编辑  收藏  举报