如何掌握Quartz.net分布式定时任务的姿势

技术如何掌握Quartz.net分布式定时任务的姿势这篇文章给大家介绍如何掌握Quartz.net分布式定时任务的姿势,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。引言长话短说,今天聊一聊分布式定时

本文介绍了如何掌握Quartz.net分布式定时任务的姿态。内容非常详细。有兴趣的朋友可以参考一下,希望对大家有帮助。

00-1010长话短说,我们今天来谈谈分布式计时任务,我的日志记录:

ASP.NET的核心Quartz.Net实施网络计时任务

AspNetCore结合Redis实践消息队列

经过仔细分析,朋友们知道还是有问题的:

水平扩展的网络应用程序的Quartz.net计时任务将被触发多次,因为网络应用程序实例使用默认的内存作业存储,多个实例在内存中维护作业和触发器的副本。

我的计时任务是同步任务,但是重复执行不是大问题。但是对于具体业务的计时任务,反复执行可能是致命的。

基于此,我们来看看Quartz.net分布式定时任务的姿态。

00-1010显然,水平扩展的多实例需要一个独立于web实例的机制来存储Job和Trigger。

提供Quartz.NET ADO.NET工作商店来存储任务数据。

首先,使用SQL脚本在数据库中生成指定的表结构。执行该脚本后,您将看到数据库中有几个以QRTZ_开头的表

quartz.config使用AdoJobStore以编码或quartz.config的形式添加配置

00-1010

引言

从https://github.com/Quartznet/Quartznet/tree/master/database/tables下载适当的数据库表脚本,以生成指定的表结构。

00-1010通过这次编码添加AdoJobStore配置。

第一次启动会将代码中的作业和触发器保存到sqlite,然后直接从sqlite加载作业和触发器。

使用系统;

使用系统。收藏品。专业化;

使用系统。数据;

使用系统。线程化。任务;

使用微软。Data . Sqlite

使用微软。扩展。日志记录;

使用石英;

使用石英。Impl

使用石英。Impl . AdoJobStore.Common

使用石英。Spi

命名空间EqidManager

{

使用IOCContainer=IServiceProvider

公共类QuartzStartup

{

公共IScheduler Scheduler { get设置;}

私有只读ILogger _ logger

私有只读IJobFactory iocJobfactory

公共QuartzStartup(Iocontainer、ILoggerFactory、LoggerFactory)

{

_logger=loggerFactory。C

reateLogger<QuartzStartup>();
           iocJobfactory = new IOCJobFactory(IocContainer);

           DbProvider.RegisterDbMetadata("sqlite-custom", new DbMetadata()
           {
               AssemblyName = typeof(SqliteConnection).Assembly.GetName().Name,
               ConnectionType = typeof(SqliteConnection),
               CommandType = typeof(SqliteCommand),
               ParameterType = typeof(SqliteParameter),
               ParameterDbType = typeof(DbType),
               ParameterDbTypePropertyName = "DbType",
               ParameterNamePrefix = "@",
               ExceptionType = typeof(SqliteException),
               BindByName = true
           });

           var properties = new NameValueCollection
           {
               ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
               ["quartz.jobStore.useProperties"] = "true",
               ["quartz.jobStore.dataSource"] = "default",
               ["quartz.jobStore.tablePrefix"] = "QRTZ_",
               ["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SQLiteDelegate, Quartz",
               ["quartz.dataSource.default.provider"] = "sqlite-custom",
               ["quartz.dataSource.default.connectionString"] = "Data Source=EqidManager.db",
               ["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz",
               ["quartz.serializer.type"] = "binary"
           };

           var schedulerFactory = new StdSchedulerFactory(properties);
           Scheduler = schedulerFactory.GetScheduler().Result;
           Scheduler.JobFactory = iocJobfactory;
       }

       public async Task<IScheduler> ScheduleJob()
       {
           var _eqidCounterResetJob = JobBuilder.Create<EqidCounterResetJob>()
             .WithIdentity("EqidCounterResetJob")
             .Build();

           var _eqidCounterResetJobTrigger = TriggerBuilder.Create()
               .WithIdentity("EqidCounterResetCron")
               .StartNow()
               //每天凌晨0s
               .WithCronSchedule("0 0 0 * * ?")      Seconds,Minutes,Hours,Day-of-Month,Month,Day-of-Week,Year(optional field)
               .Build();
       
          // 这里一定要先判断是否已经从SQlite中加载了Job和Trigger
           if (!await Scheduler.CheckExists(new JobKey("EqidCounterResetJob")) &&
               !await Scheduler.CheckExists(new TriggerKey("EqidCounterResetCron")))
           {
               await Scheduler.ScheduleJob(_eqidCounterResetJob, _eqidCounterResetJobTrigger);
           }
           
           await Scheduler.Start();
           return Scheduler;
       }

       public void EndScheduler()
       {
           if (Scheduler == null)
           {
               return;
           }

           if (Scheduler.Shutdown(waitForJobsToComplete: true).Wait(30000))
               Scheduler = null;
           else
           {
           }
           _logger.LogError("Schedule job upload as application stopped");
       }
   }
}

 

上面是Quartz.NET 从sqlite中加载Job和Trigger的核心代码

这里要提示两点:

①  IOCJobFactory 是自定义JobFactory,目的是与ASP.NET Core原生依赖注入结合
② 在调度任务的时候,先判断是否已经从sqlite加载了Job和Trigger

 

3.添加Quartz.Net UI轮子

附赠Quartz.NET的调度UI: CrystalQuartz, 方便在界面管理和调度任务
① Install-Package CrystalQuartz.AspNetCore -IncludePrerelease
② Startup启用CrystalQuartz

using CrystalQuartz.AspNetCore;
/*
* app is IAppBuilder
* scheduler is your IScheduler (local or remote)
*/
var quartz = app.ApplicationServices.GetRequiredService<QuartzStartup>();
var _schedule = await  quartz.ScheduleJob();
app.UseCrystalQuartz(() => scheduler);

 

③ 在localhost:YOUR_PORT/quartz地址查看调度

如何掌握Quartz.net分布式定时任务的姿势    

关于如何掌握Quartz.net分布式定时任务的姿势就分享到这里了,希望

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/102063.html

(0)

相关推荐

  • mysql数据库常用命令的含义(mysql列出所有数据库的命令是什么)

    技术MySQL数据库的基本命令有哪些小编给大家分享一下MySQL数据库的基本命令有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、概述数

    攻略 2021年12月21日
  • jquery如何获取tr里面有几个td

    技术jquery如何获取tr里面有几个td这篇文章主要介绍jquery如何获取tr里面有几个td,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! jquery获取tr里面

    攻略 2021年11月17日
  • Vue开发必须知道的技巧有哪些

    技术Vue开发必须知道的技巧有哪些这篇文章主要介绍“Vue开发必须知道的技巧有哪些”,在日常操作中,相信很多人在Vue开发必须知道的技巧有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”

    攻略 2021年10月20日
  • ace什么意思,女团中的ACE是什么意思

    技术ace什么意思,女团中的ACE是什么意思ACE不知道吗?没玩过英雄联盟和王者荣耀吗,还是你们从来没有ACE过对面,而放到女团中,就是能把队友团灭的人ace什么意思。而换一种说法就是,对团队做出的贡献最大,并且拥有最大

    生活 2021年10月30日
  • 什么是C++默认参数

    技术什么是C++默认参数本篇内容主要讲解“什么是C++默认参数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是C++默认参数”吧!一、C++ 默认参数通常情况下,函数在调

    攻略 2021年11月1日
  • LINQ表达式树的示例分析

    技术LINQ表达式树的示例分析小编给大家分享一下LINQ表达式树的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!using Syste

    攻略 2021年11月23日