Quartz.NET 官网 Quartz.net是什么
Quartz.NET 是一个功能齐全的开源作业调度系统,他的前身来源于java的Quartz.Quartz.net安装和使用
基于visual studio引用安装,其他IDE类似,或者下载DLL手动引用也是可以的;运行环境基于.net core,源.net程序类似 Quartz.net的架构和关键属性以及方法
三个主要的概念
- scheduler 作业调度,作业计划在给定触发器发生时运行,实际就是领导
- job 作业,实现简单 IJob 接口的任何 .NET 类,实际就是干活的员工
- trigger 侦听器,负责捕获调度事件以监视或控制作业,实际就是监工
可以这样理解:
监工发现员工偷懒了,报告给领导,领导知道后,给员工派了很多活,导致了员工天天996. 大概是这么个关系;同时呢,一个员工可以被多个监工监理,同理一个监工也可以监理多个员工,他们是多对多的关系;多个员工也可以共属于一个领导,当然也可以一个领导只有一个员工,他们直接也是多对多的关系 Quartz.net的一些关键属性
类型 | | ISchedulerFactory | SchedulerBuilder的工厂类 | IScheduler | 用于与调度程序交互的主要 API | SchedulerBuilder | 用于定义/构建调度程序实例,需要 Quartz 3.1 或更高版本 | IJobFactory | JobBuilder的工厂类 | IJob | 由您希望由调度程序执行的组件实现的接口 | IJobDetail | 用于定义作业的实例 | JobBuilder | 用于定义/构建 JobDetail 实例,这些实例定义作业的实例 | TriggerBuilder | 用于定义/构建触发器实例 | ITrigger | 定义执行给定作业的计划的一个组件,作业可以有多个关联的触发器 | ListenerManager | 侦听器事件,例如:执行job工作之前,之后触发等等,同时也可用于触发器侦听 | IServiceCollectionQuartzConfigurator 参数
Scheduler Name | 调度作业的名称 | Scheduler Id | SchedulerId | Max Batch Size | 同时执行job的最大数量 | InterruptJobsOnShutdown | | InterruptJobsOnShutdownWithWait | | BatchTriggerAcquisitionFireAheadTimeWindow | | 在通用host或者webhost中的最佳实践
通用host或者webhost代码是一样的 执行流程
- 在通用主机服务中注入服务AddQuartz,AddQuartzHostedService
- 在AddQuartz中配置调度作业的基本属性(SchedulerId等等)和调度器以及作业(ScheduleJob,AddJob,AddTrigger);可以在这个地方写入所有的调度作业,也可以写入一个initjob作业,在主机完全启动5秒后执行相应的业务(可规避掉某些依赖服务未启动的问题)
- 在initjob中,初始化其他定时任务。官网介绍job只能有一个无参的构造函数,但我亲测可以注入(笑脸)
- 关于job和reigger的具体参数,可查看官网
如下
以下代码和执行结果,其中执行顺序一目了然代码
- static void Main(string[] args)
- {
- Console.WriteLine("Hello, World!");
- LogProvider.SetCurrentLogProvider(new ConsoleLogProvider());
- //通用主机配置
- var build = Host.CreateDefaultBuilder(args)
- .ConfigureServices((host, services) =>
- {
- Console.WriteLine("--------1");
-
- //调度作业的唯一id的唯一标识,用于集群搭建cluster
- q.SchedulerId = "SchedulerId_01";
- //配置Quartz服务
- services.AddQuartz(q =>
- {
- Console.WriteLine("--------2");
- //依赖注入,ISchedulerFactory,Ijob等等
- q.UseMicrosoftDependencyInjectionJobFactory();
- //方法一和方法二使用不同方法的写法,本质基本是一样的
- //方法一
- q.ScheduleJob<InitJob>(
- trigger =>
- {
- Console.WriteLine("--------33");
- //WithIdentity 绑定触发器或者job的唯一属性和组
- //TriggerKey,JobKey 都是代表唯一个属性和组
- trigger.WithIdentity(new TriggerKey("trigger1", "triggergroup1"))
- .WithSimpleSchedule(x => x.WithIntervalInSeconds(5))
- // .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
- // .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
- .WithDescription("init 描述");
- },
- jobConfigure =>
- {
- Console.WriteLine("--------44");
- jobConfigure.WithIdentity(new JobKey("Init1", "jobgroup1"));
- }
- );
- //方法二
- //q.AddJob<InitJob>(opts =>
- //{
- // Console.WriteLine("--------3");
- // opts.WithIdentity(new JobKey("Init1", "jobgroup1"));
- //});
- //q.AddTrigger(opts =>
- //{
- // Console.WriteLine("--------4");
- // //将job添加至触发器中
- // opts.ForJob(new JobKey("Init1", "jobgroup1"))
- // .WithIdentity("trigger1", "triggergroup1")
- // .WithSimpleSchedule(x =>
- // {
- // Console.WriteLine("--------6");
- // x.WithIntervalInSeconds(5);
- // //.RepeatForever();
- // //.WithRepeatCount(5);
- // });
- //});
- });
- services.AddQuartzHostedService(options =>
- {
- options.WaitForJobsToComplete = true;
- });
- }).Build();
- //var schedulerFactory = build.Services.GetService<ISchedulerFactory>();
- //var scheduler = schedulerFactory.GetScheduler();
- build.Run();
- Console.WriteLine("--------7");
- }
- }
- public class SampleJob : IJob
- {
- public SampleJob(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
- {
- Console.WriteLine("--------8");
- }
- public async Task Execute(IJobExecutionContext context)
- {
- Console.WriteLine("--------9");
- context.JobDetail.JobDataMap.GetString("我是sample的job数据key");
- Console.WriteLine($"我是sample的job数据key: {context.JobDetail.JobDataMap.GetString("我是sample的job数据key")}");
- Console.WriteLine($"我是sample的Trigger数据key: {context.MergedJobDataMap.GetString("我是sample的Trigger数据key")}");
- }
- }
- public class InitJob : IJob
- {
- public ISchedulerFactory _schedulerFactory;
- public IJobFactory _jobFactory;
- public InitJob(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
- {
- Console.WriteLine("--------12");
- _schedulerFactory = schedulerFactory;
- _jobFactory = jobFactory;
- }
- public async Task Execute(IJobExecutionContext context)
- {
- Console.WriteLine("--------13");
- Console.WriteLine("InitJob Execute " + Random.Shared.Next(0, 100));
-
- //创建job
- IJobDetail job = JobBuilder.Create<SampleJob>()
- //写入参数
- .UsingJobData("我是sample的job数据key", "我是sample的job数据value")
- .WithIdentity("sample1", "jobgroup1").Build();
- //创建触发器
- ITrigger trigger = TriggerBuilder.Create()
- .UsingJobData("我是sample的Trigger数据key", "我是sample的Trigger数据value")
- .WithIdentity("trigger_sample1", "triggergroup1")
- .WithDescription("我是描述")
- //通过corn符号来创建触发器
- //.WithCronSchedule(taskOptions.CronExpression)
- .WithSimpleSchedule(x =>
- x.WithIntervalInSeconds(5) //5秒后执行
- .RepeatForever() //重复
- )
- .Build();
- //通过工厂获取一个作业调度
- var scheduler = await _schedulerFactory.GetScheduler();
- //绑定一个job的事件侦听器,从执行顺序上看 new JobListen是一个单例类
- scheduler.ListenerManager.AddJobListener(new JobListen(), KeyMatcher<JobKey>.KeyEquals(new JobKey("sample1", "jobgroup1")));
- //将作业和从触发器绑定至作业调度上
- await scheduler.ScheduleJob(job, trigger);
- //启动作业调度
- await scheduler.Start();
- Console.WriteLine("--------14");
- }
- }
- //作业侦听器
- public class JobListen : JobListenerSupport
- {
- public JobListen()
- {
- Console.WriteLine("--------20");
- }
- public override string Name { get { return "JobListen20"; } }
- //调用job之前执行
- public override Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken)
- {
- Console.WriteLine("--------21");
- return base.JobToBeExecuted(context, cancellationToken);
- }
- }
- //日志组件
- public class ConsoleLogProvider : ILogProvider
- {
- public Logger GetLogger(string name)
- {
- return (level, func, exception, parameters) =>
- {
- if (level >= LogLevel.Info && func != null)
- {
- Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters);
- }
- return true;
- };
- }
- public IDisposable OpenNestedContext(string message)
- {
- throw new NotImplementedException();
- }
- public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
- {
- throw new NotImplementedException();
- }
- }
复制代码 执行结果
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |