zoukankan      html  css  js  c++  java
  • 【Quartz】配置最简单的集群

      在许多情况,我们希望我们的定时任务是可靠的,不会因系统故障、机器宕机而导致某一笔定时任务不能按时运行。这种情况下,我们就需要为Quartz做个集群。

      最简单的情况,有两台机器或两个应用,同时维护一批定时任务,假如其中一个机器或应用出现问题,还有另外一个应用保底使用。

      代码与上一节【Quartz】将定时任务持久化到数据库基本一致,只列出不同的代码。

      在quartz.properties配置中设置需要集群,而集群节点的ID则由quartz自动生成

    org.quartz.jobStore.isClustered = true
    org.quartz.scheduler.instanceId = AUTO

      汇总后为

    复制代码
    org.quartz.scheduler.instanceName = MyScheduler
    org.quartz.threadPool.threadCount = 3
    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    org.quartz.jobStore.tablePrefix = QRTZ_
    org.quartz.jobStore.dataSource = myDS
    # Cluster
    org.quartz.jobStore.isClustered = true
    org.quartz.scheduler.instanceId = AUTO
    
    org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
    org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/ll?characterEncoding=utf-8
    org.quartz.dataSource.myDS.user = root
    org.quartz.dataSource.myDS.password = 123456
    org.quartz.dataSource.myDS.maxConnections = 5
    复制代码

      注:俩应用的配置应相似,除了某些特殊配置,如线程池数量、实例ID

      这里启动两个应用,其中一个应用需要注册定时任务(这里注册的定时任务每30秒运行一次);另外一个应用因集群关系则无需注册定时任务。所以,启动类有所区别。

      应用A的Bootstrap类

     1 package No01简单的定时任务;
     2 
     3 import java.util.concurrent.TimeUnit;
     4 
     5 import org.quartz.CronScheduleBuilder;
     6 import org.quartz.JobBuilder;
     7 import org.quartz.JobDetail;
     8 import org.quartz.Scheduler;
     9 import org.quartz.SchedulerException;
    10 import org.quartz.Trigger;
    11 import org.quartz.TriggerBuilder;
    12 import org.quartz.impl.StdSchedulerFactory;
    13 import org.slf4j.Logger;
    14 import org.slf4j.LoggerFactory;
    15 
    16 
    17 public class Bootstrap {
    18     private static Logger logger = LoggerFactory.getLogger(Bootstrap.class);
    19 
    20     public static void main(String[] args) {
    21 
    22         try {
    23             // 获取Scheduler实例
    24             Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    25             scheduler.start();
    26 
    27             // 具体任务
    28             JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
    29 
    30             // 触发时间点
    31             CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0,30 * * * * ? *");
    32             Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
    33                     .withSchedule(cronScheduleBuilder).build();
    34 
    35             // 交由Scheduler安排触发
    36             scheduler.scheduleJob(job, trigger);
    37             
    38             try {
    39                 TimeUnit.MINUTES.sleep(3);
    40             } catch (InterruptedException e) {
    41                 e.printStackTrace();
    42             }
    43 
    44             // 关闭Scheduler
    45             scheduler.shutdown();
    46 
    47         } catch (SchedulerException se) {
    48             logger.error(se.getMessage(), se);
    49         }
    50     }
    51 
    52 }

      应用B的Bootstrap类

     1 package No01简单的定时任务;
     2 
     3 import org.quartz.Scheduler;
     4 import org.quartz.SchedulerException;
     5 import org.quartz.impl.StdSchedulerFactory;
     6 import org.slf4j.Logger;
     7 import org.slf4j.LoggerFactory;
     8 
     9 
    10 public class Bootstrap {
    11     private static Logger logger = LoggerFactory.getLogger(Bootstrap.class);
    12 
    13     public static void main(String[] args) {
    14 
    15         try {
    16             // 获取Scheduler实例
    17             Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    18             scheduler.start();
    19 
    20         } catch (SchedulerException se) {
    21             logger.error(se.getMessage(), se);
    22         }
    23     }
    24 
    25 }

      现在,运行观察是否成功。先后启动应用A和应用B,运行并观察一段时间后,关闭应用A,继续观察。

      通过日志观察可见,首先定时任务有应用A执行,在应用A被关闭后,定时任务由应用B继续触发执行。

      注:这里观察到,似乎不是负载均衡,因为在应用A关闭后应用B才有机会运行。而我们理想中,应该是应用A与应用B互相补充、交替运行。这里主要因为只用了一个任务(只有一个触发器)做测试,如果运用多个触发器设置多个任务做测试,应用A与应用B互相补充、交替运行。

  • 相关阅读:
    (4) 编译 Android-5.0 源码
    (3) 下载 Android-5.0 源码
    (2) 搭建 Android 系统开发环境
    npm 安装 --save-dev 与 --save的使用与区别
    一点目标
    AcWing 875. 快速幂
    Codeforces Round #604 (Div. 2)
    2019年安徽大学ACM/ICPC实验室新生赛(公开赛)D 不定方程
    C语言黑与白问题
    AcWing 92. 递归实现指数型枚举
  • 原文地址:https://www.cnblogs.com/lcngu/p/6126423.html
Copyright © 2011-2022 走看看