如何掌握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)

相关推荐

  • 怎么解决PostgreSQL窗口函数调用的限制

    技术怎么解决PostgreSQL窗口函数调用的限制这篇文章主要讲解了“怎么解决PostgreSQL窗口函数调用的限制”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么解决

    攻略 2021年11月10日
  • Python环境变量的示例分析

    技术Python环境变量的示例分析这篇文章将为大家详细讲解有关Python环境变量的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Python环境变量具有一个强大灵活的工业级的

    攻略 2021年12月1日
  • 面向对象设计原则之迪米特法则

    技术面向对象设计原则之迪米特法则 面向对象设计原则之迪米特法则转载来自:https://blog.csdn.net/lovelion/article/details/7563445
    迪米特法则来自于19

    礼包 2021年11月5日
  • 40岁女人高贵优雅网名,四十岁的女人最好听的微信名字

    技术40岁女人高贵优雅网名,四十岁的女人最好听的微信名字四十岁的女人一般都比较的成熟,很多事情都会特别成熟的思考,事情处理方式也都比较成熟。那么四十岁的女人有哪些好听的微信昵称,有哪些比较合适的微信名字呢?接下来就和小编

    生活 2021年10月28日
  • 2013网游排行榜前十名,网游烧钱排行榜该怎么排

    技术2013网游排行榜前十名,网游烧钱排行榜该怎么排网游烧钱排行可以分成三档,单人投入无上限级;千万土豪级和百万富翁级2013网游排行榜前十名。单人投入无上限级:这种级别的网游有三款,在热度和规模始终确保国内畅销前列的同

    生活 2021年10月28日
  • Go语言中什么是互斥锁

    技术Go语言中什么是互斥锁这篇文章将为大家详细讲解有关Go语言中什么是互斥锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1、互斥锁Mutex1.1 Mutex介绍Go

    攻略 2021年10月21日