zoukankan      html  css  js  c++  java
  • 定时调度之Quartz

     工作中我们经常碰到定时或者固定时间点去做一些事情,然后每天到时间点就会去做这样的事情,如果理解这样的场景,我们就要引入今天我们的主角Quartz,其实这个跟数据库的作业类似,但是不仅仅局限于数据库。

    一: quartZ引入&三大核心对象简介

    1:在项目中打开Nuget管理,然后搜索QuartZ,现在最新的版本是3.0.7,需要在Framework4.5.2上面使用。

    2:quartZ的三大核心对象

    A:IScheduler:单元/实例,在这里去完成定时任务的配置,只有单元启动,里面的作业才能正常运行

    B:IJob:任务,定时执行动作就是Job

    C:ITrigger:定时策略(设置执行的频率或者执行方式)

    二:三大核心对象的初始化以及使用如下:

     1 #region scheduler
     2 Console.WriteLine("初始化scheduler......");
     3 StdSchedulerFactory factory = new StdSchedulerFactory();
     4 IScheduler scheduler = await factory.GetScheduler();
     5 //scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());
     6 //scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());
     7 //scheduler.ListenerManager.AddJobListener(new CustomJobListener());
     8 await scheduler.Start();
     9 #endregion
    10 
    11 //IJob  ITrigger
    12 {
    13     //创建作业
    14     IJobDetail jobDetail = JobBuilder.Create<TestJob>()
    15         .WithIdentity("testjob", "group1")
    16         .WithDescription("This is TestJob")
    17         .Build();
    18 
    19     //IJobDetail jobDetail = JobBuilder.Create<TestStatefulJob>()
    20     //    .WithIdentity("testjob", "group1")
    21     //    .WithDescription("This is TestJob")
    22     //    .Build();
    23 
    24     jobDetail.JobDataMap.Add("student1", "Milor");
    25     jobDetail.JobDataMap.Add("student2", "心如迷醉");
    26     jobDetail.JobDataMap.Add("student3", "宇洋");
    27     jobDetail.JobDataMap.Add("Year", DateTime.Now.Year);
    28 
    29     //ITrigger trigger = TriggerBuilder.Create()
    30     //       .WithIdentity("trigger1", "group1")
    31     //       .StartNow()
    32     //       .WithSimpleSchedule(x => x
    33     //           .WithIntervalInSeconds(10)
    34     //           .WithRepeatCount(10)
    35     //           .RepeatForever())
    36     //           .WithDescription("This is testjob's Trigger")
    37     //       .Build();
    38 
    39     //创建时间策略
    40     ITrigger trigger = TriggerBuilder.Create()
    41                   .WithIdentity("testtrigger1", "group1")
    42                   .StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(10)))
    43                  //.StartNow()//StartAt
    44                  .WithCronSchedule("5/10 * * * * ?")//每隔一分钟
    45                                                     //"10,20,30,40,50,0 * * * * ?"
    46                  .WithDescription("This is testjob's Trigger")
    47                  .Build();
    48 
    49     trigger.JobDataMap.Add("student4", "Ray");
    50     trigger.JobDataMap.Add("student5", "心欲无痕");
    51     trigger.JobDataMap.Add("student6", "风在飘动");
    52     trigger.JobDataMap.Add("Year", DateTime.Now.Year + 1);
    53 
    54     await scheduler.ScheduleJob(jobDetail, trigger);
    55     Console.WriteLine("scheduler作业添加完成......");
    56 }
    View Code
     1  public class TestJob : IJob
     2  {
     3      public TestJob()
     4         {
     5             Console.WriteLine("This is TestJob的构造。。。");
     6         }
     7      
     8      public async Task Execute(IJobExecutionContext context)
     9         {
    10             await Task.Run(() =>
    11             {
    12                 Console.WriteLine();
    13                 Console.WriteLine("*****************************");
    14                 {
    15                     JobDataMap dataMap = context.JobDetail.JobDataMap;
    16                     Console.WriteLine(dataMap.Get("student1"));
    17                     Console.WriteLine(dataMap.Get("student2"));
    18                     Console.WriteLine(dataMap.Get("student3"));
    19                     Console.WriteLine(dataMap.GetInt("Year"));
    20                 }
    21                 Console.WriteLine($"This is {Thread.CurrentThread.ManagedThreadId} {DateTime.Now}");
    22                 //可以换成去数据库查询,可以做啥啥啥
    23                 //但是很多情况下,我们也是需要参数的
    24                 {
    25                     JobDataMap dataMap = context.Trigger.JobDataMap;
    26                     Console.WriteLine(dataMap.Get("student4"));
    27                     Console.WriteLine(dataMap.Get("student5"));
    28                     Console.WriteLine(dataMap.Get("student6"));
    29                     Console.WriteLine(dataMap.GetInt("Year"));
    30                 }
    31                 {
    32                     Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
    33                     JobDataMap dataMap = context.MergedJobDataMap;
    34                     Console.WriteLine(dataMap.Get("student1"));
    35                     Console.WriteLine(dataMap.Get("student2"));
    36                     Console.WriteLine(dataMap.Get("student3"));
    37                     Console.WriteLine(dataMap.Get("student4"));
    38                     Console.WriteLine(dataMap.Get("student5"));
    39                     Console.WriteLine(dataMap.Get("student6"));
    40                     Console.WriteLine(dataMap.GetInt("Year"));
    41                 }
    42                 Console.WriteLine("*****************************");
    43                 Console.WriteLine();
    44             });
    45         }
    46  }
    View Code

    三:任务或者定时策略传参

    1:通过定时任务进行传参如下:

    然后接收通过:

     2:定时策略进行传参

    接收如下:

    注意以上两种传参也可以统一通过下面的方式来接收参数,但是如果key相同,则会进行覆盖掉

    四:常用的Trigggr

    1:SimpleTrigger:从什么时间开始,间隔多久执行重复操作,可以限制最大次数,如下:

    1  ITrigger trigger = TriggerBuilder.Create()
    2         .WithIdentity("trigger1", "group1")
    3         .StartNow()
    4         .WithSimpleSchedule(x => x
    5             .WithIntervalInSeconds(10)
    6             .WithRepeatCount(10)
    7             .RepeatForever()) //从什么时间开始,间隔多久执行重复操作,可以限制最大次数
    8             .WithDescription("This is testjob's Trigger")
    9         .Build();

    2:Cron:表达式的方式,可以灵活订制时间规则(具体详情咨询

    1 ITrigger trigger = TriggerBuilder.Create()
    2               .WithIdentity("testtrigger1", "group1")
    3               .StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(10)))
    4              //.StartNow()//StartAt
    5              .WithCronSchedule("5/10 * * * * ?")//每隔一分钟 //"10,20,30,40,50,0 * * * * ?"
    6              .WithDescription("This is testjob's Trigger")
    7              .Build();

    五:Listener框架的各个环节--事件能做的监听

    如果我们自己写定时任务的时候,因为是定时或者周期去做一些事情,所以有时候有问题或者出现了什么故障,我们只能通过我们自己写一下具体的日志,但是Quartz里面的Listener里面内置封装了一些监听接口,分别为:ISchedulerListener,ITriggerListener,IJobListener,里面有一些方法可以让我们去做一下其它的事情,我们下面分别实现了三个接口,代码如下:

    1:jobListerer

     1 public class CustomJobListener : IJobListener
     2     {
     3         public string Name => "CustomJobListener";
     4 
     5         public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
     6         {
     7             await Task.Run(()=> {
     8                 Console.WriteLine($"CustomJobListener JobExecutionVetoed {context.JobDetail.Description}");
     9             });
    10         }
    11 
    12         public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
    13         {
    14             await Task.Run(() => {
    15                 Console.WriteLine($"CustomJobListener JobToBeExecuted {context.JobDetail.Description}");
    16             });
    17         }
    18 
    19         public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
    20         {
    21             await Task.Run(() => {
    22                 Console.WriteLine($"CustomJobListener JobWasExecuted {context.JobDetail.Description}");
    23             });
    24         }
    25     }
    View Code

    2:ITriggerListener

     1 public class CustomTriggerListener : ITriggerListener
     2     {
     3         public string Name => "CustomTriggerListener";
     4 
     5         public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
     6         {
     7             await Task.Run(() =>
     8             {
     9                 Console.WriteLine($"CustomTriggerListener TriggerComplete {trigger.Description}");
    10             });
    11         }
    12 
    13         public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
    14         {
    15             await Task.Run(() =>
    16             {
    17                 Console.WriteLine($"CustomTriggerListener TriggerFired {trigger.Description}");
    18             });
    19         }
    20 
    21         public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
    22         {
    23             await Task.Run(() =>
    24             {
    25                 Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
    26             });
    27         }
    28 
    29         /// <summary>
    30         /// 要不要放弃job
    31         /// </summary>
    32         /// <param name="trigger"></param>
    33         /// <param name="context"></param>
    34         /// <param name="cancellationToken"></param>
    35         /// <returns></returns>
    36         public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
    37         {
    38             await Task.Run(() =>
    39             {
    40                 Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
    41             });
    42             return false;//false才能继续执行
    43         }
    44     }
    View Code

    3:ISchedulerListener

      1 public class CustomSchedulerListener : ISchedulerListener
      2     {
      3         public async Task JobAdded(IJobDetail jobDetail, CancellationToken cancellationToken = default(CancellationToken))
      4         {
      5             await Task.Run(() =>
      6             {
      7                 Console.WriteLine($"This is {nameof(CustomSchedulerListener)} JobAdded {jobDetail.Description}");
      8             });
      9         }
     10 
     11         public Task JobDeleted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
     12         {
     13             throw new NotImplementedException();
     14         }
     15 
     16         public Task JobInterrupted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
     17         {
     18             throw new NotImplementedException();
     19         }
     20 
     21         public Task JobPaused(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
     22         {
     23             throw new NotImplementedException();
     24         }
     25 
     26         public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
     27         {
     28             throw new NotImplementedException();
     29         }
     30 
     31         public Task JobScheduled(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
     32         {
     33             throw new NotImplementedException();
     34         }
     35 
     36         public Task JobsPaused(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
     37         {
     38             throw new NotImplementedException();
     39         }
     40 
     41         public Task JobsResumed(string jobGroup, CancellationToken cancellationToken = default(CancellationToken))
     42         {
     43             throw new NotImplementedException();
     44         }
     45 
     46         public Task JobUnscheduled(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
     47         {
     48             throw new NotImplementedException();
     49         }
     50 
     51         public Task SchedulerError(string msg, SchedulerException cause, CancellationToken cancellationToken = default(CancellationToken))
     52         {
     53             throw new NotImplementedException();
     54         }
     55 
     56         public Task SchedulerInStandbyMode(CancellationToken cancellationToken = default(CancellationToken))
     57         {
     58             throw new NotImplementedException();
     59         }
     60 
     61         public Task SchedulerShutdown(CancellationToken cancellationToken = default(CancellationToken))
     62         {
     63             throw new NotImplementedException();
     64         }
     65 
     66         public Task SchedulerShuttingdown(CancellationToken cancellationToken = default(CancellationToken))
     67         {
     68             throw new NotImplementedException();
     69         }
     70 
     71         public async Task SchedulerStarted(CancellationToken cancellationToken = default(CancellationToken))
     72         {
     73             await Task.Run(() =>
     74             {
     75                 Console.WriteLine($"This is {nameof(CustomSchedulerListener)} SchedulerStarted ");
     76             });
     77         }
     78 
     79         public async Task SchedulerStarting(CancellationToken cancellationToken = default(CancellationToken))
     80         {
     81             await Task.Run(() =>
     82             {
     83                 Console.WriteLine($"This is {nameof(CustomSchedulerListener)} SchedulerStarting ");
     84             });
     85         }
     86 
     87         public Task SchedulingDataCleared(CancellationToken cancellationToken = default(CancellationToken))
     88         {
     89             throw new NotImplementedException();
     90         }
     91 
     92         public Task TriggerFinalized(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
     93         {
     94             throw new NotImplementedException();
     95         }
     96 
     97         public Task TriggerPaused(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
     98         {
     99             throw new NotImplementedException();
    100         }
    101 
    102         public Task TriggerResumed(TriggerKey triggerKey, CancellationToken cancellationToken = default(CancellationToken))
    103         {
    104             throw new NotImplementedException();
    105         }
    106 
    107         public Task TriggersPaused(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
    108         {
    109             throw new NotImplementedException();
    110         }
    111 
    112         public Task TriggersResumed(string triggerGroup, CancellationToken cancellationToken = default(CancellationToken))
    113         {
    114             throw new NotImplementedException();
    115         }
    116     }
    View Code

    然后通过下面代码来融合到实例中:

    1  StdSchedulerFactory factory = new StdSchedulerFactory();
    2             IScheduler scheduler = await factory.GetScheduler();
    3             scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());
    4             scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());
    5             scheduler.ListenerManager.AddJobListener(new CustomJobListener());
    6             await scheduler.Start();

    这样就完美的结合在一起了,然后实例,任务,策略每次发生的动作,都会以日志的形式输出来,当然可以记录任何形式的日志。

    六:LogProvider可以展示框架运行的一些信息

    Quartz.Logging内置了一些记录日志的类,然后需要记录日志的话,可以直接拿来使用,不用自己再去引用配置等记录日志了,下面是自己试着写了一个:

     1 public class CustomConsoleLogProvider : ILogProvider
     2     {
     3         public Logger GetLogger(string name)
     4         {
     5             return new Logger((level, func, exception, parameters) =>
     6             {
     7                 if (level >= LogLevel.Info && func != null)
     8                 {
     9                     Console.WriteLine($"[{ DateTime.Now.ToLongTimeString()}] [{ level}] { func()} {string.Join(";", parameters.Select(p => p == null ? " " : p.ToString()))}  自定义日志{name}");
    10                 }
    11                 return true;
    12             });
    13         }
    14         public IDisposable OpenNestedContext(string message)
    15         {
    16             throw new NotImplementedException();
    17         }
    18 
    19         public IDisposable OpenMappedContext(string key, string value)
    20         {
    21             throw new NotImplementedException();
    22         }
    23     }
    View Code

    然后在DispatcherManager中的init方法中

     这样即实现了log的日志

    如果想要测试,可以通过:

     1  static void Main(string[] args)
     2  {
     3      try
     4      {
     5          Console.WriteLine("QuartZ.Net定时调度");
     6          DispatcherManager.Init().GetAwaiter().GetResult();
     7      }
     8      catch (Exception ex)
     9      {
    10          Console.WriteLine(ex.Message);
    11      }
    12      Console.Read();
    13  }
    View Code
  • 相关阅读:
    web-火狐浏览器下载地址
    如何使用jmeter录制app脚本
    Jmeter参数化(jmter和badboy的配合使用)
    monkey常用命令详解(多参数化)
    monkey常用命令
    mysql数据库命令
    Linux命令
    循环语句的使用
    K8S学习笔记一:K8S的基础概念
    jmeter做尖峰测试(浪潮测试)
  • 原文地址:https://www.cnblogs.com/loverwangshan/p/11005312.html
Copyright © 2011-2022 走看看