zoukankan      html  css  js  c++  java
  • .net 5中配置Quartz集群

    准备工作:

    Quartz.net官方关于配置集群的文档:https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/job-stores.html#ramjobstore

    本篇文章内容参考自:https://www.cnblogs.com/JulianHuang/p/12720436.html

    1、数据库中添加几张表

    根据自己的数据库类型,自行进入这个地址复制SQL执行:https://github.com/quartznet/quartznet/tree/master/database/tables

    以下内容均以 Mysql 为例

    2、修改startup中依赖注入的代码


    改为:

    services.AddSingleton<ISchedulerFactory>(u => {
        DbProvider.RegisterDbMetadata("mysql-custom", new DbMetadata()
        {
            AssemblyName = typeof(MySqlConnection).Assembly.GetName().Name,
            ConnectionType = typeof(MySqlConnection),
            CommandType = typeof(MySqlCommand),
            ParameterType = typeof(MySqlParameter),
            ParameterDbType = typeof(DbType),
            ParameterDbTypePropertyName = "DbType",
            ParameterNamePrefix = "@",
            ExceptionType = typeof(MySqlException),
            BindByName = true
       });
       var properties = new NameValueCollection
       {
           ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", // 配置Quartz以使用JobStoreTx
           ["quartz.jobStore.useProperties"] = "true", // 配置AdoJobStore以将字符串用作JobDataMap值
           ["quartz.jobStore.dataSource"] = "myDS", // 配置数据源名称
           ["quartz.jobStore.tablePrefix"] = "QRTZ_", // quartz所使用的表,在当前数据库中的表前缀
           ["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz",  // 配置AdoJobStore使用的DriverDelegate
           ["quartz.dataSource.myDS.connectionString"] = "server=localhost;uid=root;pwd=123;database=quartzsample", // 配置数据库连接字符串,自己处理好连接字符串,我这里就直接这么写了
           ["quartz.dataSource.myDS.provider"] = "mysql-custom", // 配置数据库提供程序(这里是自定义的,定义的代码在上面)
           ["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz",
           ["quartz.serializer.type"] = "binary",
           ["quartz.jobStore.clustered"] = "true",    //  指示Quartz.net的JobStore是应对 集群模式
           ["quartz.scheduler.instanceId"] = "AUTO"
        };
        return new StdSchedulerFactory(properties);
    });
    

    注意改一下数据库连接字符串

    3、修改 QuartzHostedService 类


    修改 StartAsync 这个方法的内容,在 foreach 循环体内部添加一行 if 判断语句
    原来的代码为:

    需要改成:

     /// <summary>
     /// 批量启动定时任务
     /// </summary>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
     public async Task StartAsync(CancellationToken cancellationToken)
     {
         _scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
         _scheduler.JobFactory = _jobFactory;
    
         // 循环遍历startup里注册的作业
         foreach (var jobSchedule in _jobSchedules)
         {
             // 判断数据库中有没有记录过,有的话,quartz会自动从数据库中提取信息创建 schedule
             if (!await _scheduler.CheckExists(new JobKey(GenerateIdentity(jobSchedule, IdentityType.Job))) &&
              !await _scheduler.CheckExists(new TriggerKey(GenerateIdentity(jobSchedule, IdentityType.Trigger))))
             {
                 var job = CreateJob(jobSchedule);
                 var trigger = CreateTrigger(jobSchedule);
    
                 await _scheduler.ScheduleJob(job, trigger, cancellationToken);
             }
         }
    
         await _scheduler.Start();
    }
    

    3、目前集群已配置完成,进入项目根目录,开三个 cmd 用来在本地模拟集群


    复制下面这条语句,粘贴到 cmd,然后每个 cmd 里面都修改成不同的端口号

    dotnet run --urls=http://*:10086
    

    首先先只运行两个程序,然后观察规律

    仔细观察两个端口,你可以发现,同样的代码,但是定时任务并不会同时被两个进程去执行,他只会执行一个,那现在我把右边的给停下来

    这个时候你就能发现,右边那个停止之后,左边的不仅会执行 job2 ,而且还会执行 job1
    那如果是三个又会怎么样呢

    现在我再把两边的给关掉,只留中间的那个

    Quartz借助数据库,使用悲观锁的方式,达到即使部署了多台机器,同一个定时任务也不会连续被几台服务机一起执行的结果。当一台机挂了,这时其他机器接过上台机的接力棒继续跑,从而做到高可用。

    本篇文章代码地址:https://github.com/book12138/QuartzSample

  • 相关阅读:
    Asp.net使用DevExpress的某些控件不能操作ViewState的解决方案
    关于 vue 循环组件,组件内有根据要求请求select下拉列表,组件内还有自身组件,select下拉列表无法正确获取的问题解决
    Vue+axios请求本地json
    关于vuevideoplayer 实现跳转到特定位置并自动播放
    VueQuillEditor回显不显示空格的处理办法
    elementui 的CascaderPanel级联面板类型 懒加载 回显
    elementui 中的文本域的autosize的意思
    解决 [Element Warn][Form]model is required for validate to work!
    初涉simulink
    arm学习计划
  • 原文地址:https://www.cnblogs.com/shapman/p/14218712.html
Copyright © 2011-2022 走看看