.Net Core 使用 Quartz快速入门

一、需求场景

我们在日常开发中,总会遇到这样的需求:

  1. 每隔一段时间,执行一次某个任务。
  2. 固定某个时间执行任务,例如凌晨12点对当天的数据进行统计。
  3. 每个月的第几天,执行某个任务。

诸如此类的需求很多,我们总不能人工去干这件事吧 ?所以我们需要引入作业调度工具,也就是今天的主角——Quartz。

二、Quartz基本介绍

2.1Quartz概述

Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。读者可以到 http://www.quartz-scheduler.org/站点下载 Quartz 的发布版本及其源代码。

2.2Quartz的特点

作为一个优秀的开源调度框架,Quartz 具有以下特点:

强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;
灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
分布式和集群能力,Terracotta 收购后在原来功能基础上作了进一步提升。

三、使用Quartz

此次我将建立一个.net Core 3.1 MVC项目进行演示

1、NuGet引入Quartz,目前为止Quartz的最新版本为3.0.7。

2、注册ISchedulerFactory的实例。

切换至Startup类,在ConfigureServices方法中添加如下代码

services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();

 

3、创建作业

 我们添加一个Jobs的类,继承Ijob接口

Jobs类中的Execute方法,多线程的向我们的D盘中的message.log文本文件中写入当前时间。

3.代码演示。

切换到HomeController ,正式开始撸代码

 public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly ISchedulerFactory _schedulerFactory;
        private IScheduler _scheduler;
 
        public HomeController(ILogger<HomeController> logger, ISchedulerFactory schedulerFactory)
        {
            _logger = logger;
            _schedulerFactory = schedulerFactory;
        }
 
        public async Task<IActionResult> Index()
        {
            //通过工场类获得调度器
            _scheduler = await _schedulerFactory.GetScheduler();
            //开启调度器
            await _scheduler.Start();
            //创建触发器(也叫时间策略)
            var trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever())//每10秒执行一次
                            .Build();
            //创建作业实例
            //Jobs即我们需要执行的作业
            var jobDetail = JobBuilder.Create<Jobs>()
                            .WithIdentity("Myjob", "group")//我们给这个作业取了个“Myjob”的名字,并取了个组名为“group”
                            .Build();
            //将触发器和作业任务绑定到调度器中
            await _scheduler.ScheduleJob(jobDetail, trigger);
            return View();
        }
 
        public IActionResult Privacy()
        {
            return View();
        }

  

4、运行结果

可以看到程序每隔10秒就会向message文件写入一行当前时间。

四、更多时间策略

文章开篇我们就列举了几种常见的业务需求,上面的案例中,我们演示了10秒钟执行一次的效果。如果需要以分钟、小时、天等作为单位,甚至是更为复杂的时间策略,如何定制呢?

 

.Net Core 使用 Quartz快速入门(二)

一、Trigger策略

Quartz中有两种Trigger策略分别是:

  1. Simple Trigger

  2. CronTrigger

二、 Simple Trigger

SimpleTrigger可以满足的调度需求是:在具体的时间点执行一次,或者在具体的时间点执行,并且以指定的间隔重复执行若干次。比如,你有一个trigger,你可以设置它在2015年1月13日的上午11:23:54准时触发,或者在这个时间点触发,并且每隔2秒触发一次,一共重复5次。

根据描述,你可能已经发现了,SimpleTrigger的属性包括:开始时间、结束时间、重复次数以及重复的间隔。这些属性的含义与你所期望的是一致的,只是关于结束时间有一些地方需要注意。

重复次数,可以是0、正整数,以及常量SimpleTrigger.REPEAT_INDEFINITELY。重复的间隔,必须是0,或者long型的正数,表示毫秒。注意,如果重复间隔为0,trigger将会以重复次数并发执行(或者以scheduler可以处理的近似并发数)。

如果你还不熟悉DateBuilder,了解后你会发现使用它可以非常方便地构造基于开始时间(或终止时间)的调度策略。

endTime属性的值会覆盖设置重复次数的属性值;比如,你可以创建一个trigger,在终止时间之前每隔10秒执行一次,你不需要去计算在开始时间和终止时间之间的重复次数,只需要设置终止时间并将重复次数设置为REPEAT_INDEFINITELY(当然,你也可以将重复次数设置为一个很大的值,并保证该值比trigger在终止时间之前实际触发的次数要大即可)。

1、每10秒执行一次,重复5次,共6次

var trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).WithRepeatCount(5))//每10秒执行一次,重复5次,共6次
                            .Build();

 

2、5分钟以后开始触发,仅执行一次

var trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule()
                            .StartAt(DateTimeOffset.Now.AddMinutes(5))
                            .Build();

 

3、立即触发,每个5分钟执行一次,直到10:30:15

var trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule(x => x.WithIntervalInMinutes(5).RepeatForever())
                            .EndAt(DateBuilder.DateOf(10, 30, 15))
                            .Build();

 

4、在下一个小时的整点触发,然后每2小时重复一次 

var trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule(x => x.WithIntervalInHours(2).RepeatForever())
                            .StartAt(DateBuilder.EvenHourDate(null))
                            .Build();

 

三、CronTrigger 

CronTrigger通常比Simple Trigger更有用,如果您需要基于日历的概念而不是按照SimpleTrigger的精确指定间隔进行重新启动的作业启动计划。

使用CronTrigger,您可以指定号时间表,例如“每周五中午”或“每个工作日和上午9:30”,甚至“每周一至周五上午9:00至10点之间每5分钟”和1月份的星期五“。

即使如此,和SimpleTrigger一样,CronTrigger有一个startTime,它指定何时生效,以及一个(可选的)endTime,用于指定何时停止计划。

Cron Expressions

Cron-Expressions用于配置CronTrigger的实例。Cron Expressions是由七个子表达式组成的字符串,用于描述日程表的各个细节。这些子表达式用空格分隔,并表示:

  1. Seconds
  2. Minutes
  3. Hours
  4. Day-of-Month
  5. Month
  6. Day-of-Week
  7. Year (optional field)

Cron Expressions示例

CronTrigger示例1 - 创建一个触发器的表达式,每5分钟就会触发一次

“0 0/5 * * *?”

CronTrigger示例2 - 创建触发器的表达式,每5分钟触发一次,分钟后10秒(即上午10时10分,上午10:05:10等)。

“10 0/5 * * *?”

CronTrigger示例3 - 在每个星期三和星期五的10:30,11:30,12:30和13:30创建触发器的表达式。

“0 30 10-13?* WED,FRI“

CronTrigger示例4 - 创建触发器的表达式,每个月5日和20日上午8点至10点之间每半小时触发一次。请注意,触发器将不会在上午10点开始,仅在8:00,8:30,9:00和9:30

“0 0/30 8-9 5,20 *?”

请注意,一些调度要求太复杂,无法用单一触发表示 - 例如“每上午9:00至10:00之间每5分钟,下午1:00至晚上10点之间每20分钟”一次。在这种情况下的解决方案是简单地创建两个触发器,并注册它们来运行相同的作业。

 1、每天上午8点至下午5点之间,每隔一分钟执行

var trigger = TriggerBuilder.Create()
                .WithCronSchedule("0 0/2 8-17 * * ?")
                .Build();

  

2、 将在每天上午8:30执行

var trigger = TriggerBuilder.Create()
                .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(8, 30))
                .Build();

 

3、将在星期三上午10:42执行

var trigger = TriggerBuilder.Create()
                .WithCronSchedule("0 42 10 ? * WED", x => x
                .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")))

 

 

 Quartz的Trigger示例就介绍到这里,你们是否有疑问,如果我们的Job是需要传递参数的,那使用Quartz如何给Job传递参数呢?咱们且听下回分解。

 

版权声明:本文为CSDN博主「林深时见禄」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaolu1014/article/details/103880704

posted @ 2021-08-24 14:46  天健地坤  阅读(1384)  评论(0)    收藏  举报