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

相关推荐

  • Oracle R12如何安装日志和其他日志

    技术Oracle R12如何安装log及其他log小编给大家分享一下Oracle R12如何安装log及其他log,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们

    攻略 2021年12月16日
  • scapy抓包使用

    技术scapy抓包使用 scapy抓包使用# coding=utf-8
    import json
    import time
    import os
    import dpkt
    import socket
    impor

    礼包 2021年11月19日
  • 如何构建MongoDB RepSet +Consul高可用切换系统

    技术如何构建MongoDB RepSet +Consul高可用切换系统小编给大家分享一下如何构建MongoDB RepSet +Consul高可用切换系统,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望

    攻略 2021年11月24日
  • Gatling的相关知识点有哪些

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

    攻略 2021年11月12日
  • Centos8 下部署 ASP.net Core 程序

    技术Centos8 下部署 ASP.net Core 程序 Centos8 下部署 ASP.net Core 程序1、安装需要的SDK包,如果程序包含3.1版本,需要安装3.1的SDK。
    sudo dn

    礼包 2021年12月1日
  • c++编译器(c++用什么软件编程)

    技术将C++ 类型属性暴露给QML的示例分析这期内容当中小编将会给大家带来有关将C++ 类型属性暴露给QML的示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、数据类型处理和所

    攻略 2021年12月15日