在Ovirt中使用Quzrtz

发布于:2023-03-01 ⋅ 阅读:(258) ⋅ 点赞:(0)

什么是Quartz

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:

持久性作业 - 就是保持调度定时的状态;
作业管理 - 对调度作业进行有效的管理; 

Quartz在ovirt中的配置

  1. 配置文件 backend/manager/modules/scheduler/src/main/resources/ovirt-db-scheduler.properties

    org.quartz.scheduler.instanceName=QuartzOvirtDBScheduler
    org.quartz.scheduler.skipUpdateCheck=true
    org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true
    org.quartz.jobStore.useProperties=false
    org.quartz.jobStore.lockOnInsert=false
    org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreCMT
    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    org.quartz.jobStore.dataSource=EngineDS
    org.quartz.threadPool.class=org.ovirt.engine.core.utils.timer.SchedulerThreadPool
    org.quartz.threadPool.threadCount=50
    org.quartz.jobStore.nonManagedTXDataSource=NMEngineDS
    org.quartz.dataSource.EngineDS.jndiURL=java:/ENGINEDataSource
    org.quartz.dataSource.NMEngineDS.jndiURL=java:/ENGINEDataSourceNoJTA
  2. 工具类
    backend/manager/modules/scheduler/src/main/java/org/ovirt/engine/core/utils/timer/SchedulerUtil.java
    工具接口:包含系统启动时quartz创建,schedule调度的各种方法

    //固定频率任务
    public String scheduleAFixedDelayJob(Object instance,
                                          String methodName,
                                          Class<?>[] inputTypes,
                                          Object[] inputParams,
                                          long initialDelay,
                                          long taskDelay,
                                          TimeUnit timeUnit);
    //一次性任务
    public String scheduleAOneTimeJob(Object instance,
                                       String methodName,
                                       Class<?>[] inputTypes,
                                       Object[] inputParams,
                                       long initialDelay,
                                       TimeUnit timeUnit);
    //cron任务
    String scheduleACronJob(Object instance,
                             String methodName,
                             Class<?>[] inputTypes,
                             Object[] inputParams,
                             String cronExpression);
    //重新安排任务
    void rescheduleAJob(String oldTriggerName, String oldTriggerGroup, Trigger newTrigger);
    //暂停任务
    public void pauseJob(String jobId);
    //删除任务
    public void deleteJob(String jobId);
    //恢复任务                              
    public void resumeJob(String jobId); 
    //获取调度对象,可通过该方法调用quartz原生方法
    Scheduler getRawScheduler();
  3. 涉及到的表及表字段

    qrtz_blob_triggers : 以Blob 类型存储的触发器。
    qrtz_calendars:存放日历信息, quartz可配置一个日历来指定一个时间范围。
    qrtz_cron_triggers:存放cron类型的触发器。
    qrtz_fired_triggers:存放已触发的触发器
    qrtz_job_details:存放一个jobDetail信息。
    qrtz_job_listeners:job监听器。
    qrtz_locks: 存储程序的悲观锁的信息(假如使用了悲观锁)。
    qrtz_paused_trigger_graps:存放暂停掉的触发器。
    qrtz_scheduler_state:调度器状态。
    qrtz_simple_triggers:简单触发器的信息。
    qrtz_triggers:触发器的基本信息。

    表字段说明

  4. qrtz_blob_triggers
    自定义触发器表,用的不太多

    CREATE TABLE `qrtz_blob_triggers` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `TRIGGER_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器群组',
      `BLOB_DATA` blob COMMENT '基本信息',
      PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      CONSTRAINT `qrtz_blob_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore并不知道如何存储实例的时候';
  5. qrtz_calendars
    日历信息触发器

    CREATE TABLE `qrtz_calendars` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `CALENDAR_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `CALENDAR` blob NOT NULL COMMENT '日历信息',
      PRIMARY KEY (`SCHED_NAME`,`CALENDAR_NAME`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='日历信息触发器';
  6. qrtz_cron_triggers
    cron 表达式用的特别多。在线cron表达式生成地址

    CREATE TABLE `qrtz_cron_triggers` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `TRIGGER_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器群组',
      `CRON_EXPRESSION` varchar(120) NOT NULL COMMENT 'cron表达式',
      `TIME_ZONE_ID` varchar(80) DEFAULT NULL COMMENT '时区',
      PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      CONSTRAINT `qrtz_cron_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='cron触发器';
  7. qrtz_fired_triggers

    CREATE TABLE `qrtz_fired_triggers` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `ENTRY_ID` varchar(95) NOT NULL COMMENT '组织id',
      `TRIGGER_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器组',
      `INSTANCE_NAME` varchar(200) NOT NULL COMMENT '实例名称',
      `FIRED_TIME` bigint(13) NOT NULL COMMENT '触发时间',
      `SCHED_TIME` bigint(13) NOT NULL COMMENT '计划时间',
      `PRIORITY` int(11) NOT NULL COMMENT '权重',
      `STATE` varchar(16) NOT NULL COMMENT '状态',
      `JOB_NAME` varchar(200) DEFAULT NULL COMMENT '作业名称',
      `JOB_GROUP` varchar(200) DEFAULT NULL COMMENT '作业群组',
      `IS_NONCONCURRENT` varchar(1) DEFAULT NULL COMMENT '是否并行',
      `REQUESTS_RECOVERY` varchar(1) DEFAULT NULL COMMENT '是否要求唤醒',
      PRIMARY KEY (`SCHED_NAME`,`ENTRY_ID`),
      KEY `IDX_QRTZ_FT_TRIG_INST_NAME` (`SCHED_NAME`,`INSTANCE_NAME`),
      KEY `IDX_QRTZ_FT_INST_JOB_REQ_RCVRY` (`SCHED_NAME`,`INSTANCE_NAME`,`REQUESTS_RECOVERY`),
      KEY `IDX_QRTZ_FT_J_G` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
      KEY `IDX_QRTZ_FT_JG` (`SCHED_NAME`,`JOB_GROUP`),
      KEY `IDX_QRTZ_FT_T_G` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      KEY `IDX_QRTZ_FT_TG` (`SCHED_NAME`,`TRIGGER_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger组的信息';
  8. qrtz_job_details

    CREATE TABLE `qrtz_job_details` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '调度器名称',
      `JOB_NAME` varchar(200) NOT NULL COMMENT '任务名称',
      `JOB_GROUP` varchar(200) NOT NULL COMMENT '任务群组',
      `DESCRIPTION` varchar(250) DEFAULT NULL COMMENT '说明',
      `JOB_CLASS_NAME` varchar(250) NOT NULL COMMENT '任务class全路径',
      `IS_DURABLE` varchar(1) NOT NULL,
      `IS_NONCONCURRENT` varchar(1) NOT NULL,
      `IS_UPDATE_DATA` varchar(1) NOT NULL,
      `REQUESTS_RECOVERY` varchar(1) NOT NULL,
      `JOB_DATA` blob,
      PRIMARY KEY (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
      KEY `IDX_QRTZ_J_REQ_RECOVERY` (`SCHED_NAME`,`REQUESTS_RECOVERY`),
      KEY `IDX_QRTZ_J_GRP` (`SCHED_NAME`,`JOB_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  9. qrtz_locks

    CREATE TABLE `qrtz_locks` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `LOCK_NAME` varchar(40) NOT NULL COMMENT '锁名称',
      PRIMARY KEY (`SCHED_NAME`,`LOCK_NAME`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='通过悲观锁获取触发器';

    在集群模式下,通过悲观锁来保证触发器有序的获取。

  10. qrtz_paused_trigger_grps

    CREATE TABLE `qrtz_paused_trigger_grps` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器组',
      PRIMARY KEY (`SCHED_NAME`,`TRIGGER_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='被暂停的触发器';
  11. qrtz_scheduler_state

    CREATE TABLE `qrtz_scheduler_state` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '调度器名称',
      `INSTANCE_NAME` varchar(200) NOT NULL,
      `LAST_CHECKIN_TIME` bigint(13) NOT NULL COMMENT '最后验证时间',
      `CHECKIN_INTERVAL` bigint(13) NOT NULL COMMENT '时间间隔',
      PRIMARY KEY (`SCHED_NAME`,`INSTANCE_NAME`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    集群模式下,一般每一个服务对应表中的一条数据。并且定时更新表的LAST_CHECKIN_TIME字段,来说明自己是存或状态。在没有zookeeper的情况下,在判断服务存或的时候,这种方式也算是一种相对较好的方式。SCHED_NAME的名字可通过配置进行修改。

  12. qrtz_simple_triggers

    CREATE TABLE `qrtz_simple_triggers` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `TRIGGER_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器组',
      `REPEAT_COUNT` bigint(7) NOT NULL COMMENT '重复次数',
      `REPEAT_INTERVAL` bigint(12) NOT NULL COMMENT '重复间隔',
      `TIMES_TRIGGERED` bigint(10) NOT NULL COMMENT '触发次数',
      PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      CONSTRAINT `qrtz_simple_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `qrtz_triggers` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储简单的Trigger,包括重复次数,间隔,以及已触的次数';

    10.qrtz_triggers

    CREATE TABLE `qrtz_triggers` (
      `SCHED_NAME` varchar(120) NOT NULL COMMENT '计划名称',
      `TRIGGER_NAME` varchar(200) NOT NULL COMMENT '触发器名称',
      `TRIGGER_GROUP` varchar(200) NOT NULL COMMENT '触发器群组',
      `JOB_NAME` varchar(200) NOT NULL COMMENT '作业名称',
      `JOB_GROUP` varchar(200) NOT NULL COMMENT '作业群组',
      `DESCRIPTION` varchar(250) DEFAULT NULL COMMENT '说明信息',
      `NEXT_FIRE_TIME` bigint(13) DEFAULT NULL COMMENT '下次执行时间',
      `PREV_FIRE_TIME` bigint(13) DEFAULT NULL COMMENT '上次执行时间',
      `PRIORITY` int(11) DEFAULT NULL COMMENT '线程优先级',
      `TRIGGER_STATE` varchar(16) NOT NULL COMMENT '触发状态此字段很重要',
      `TRIGGER_TYPE` varchar(8) NOT NULL COMMENT '触发器类型',
      `START_TIME` bigint(13) NOT NULL COMMENT '开始时间',
      `END_TIME` bigint(13) DEFAULT NULL COMMENT '结束时间',
      `CALENDAR_NAME` varchar(200) DEFAULT NULL COMMENT '日历名称',
      `MISFIRE_INSTR` smallint(2) DEFAULT NULL,
      `JOB_DATA` blob,
      PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`),
      KEY `IDX_QRTZ_T_J` (`SCHED_NAME`,`JOB_NAME`,`JOB_GROUP`),
      KEY `IDX_QRTZ_T_JG` (`SCHED_NAME`,`JOB_GROUP`),
      KEY `IDX_QRTZ_T_C` (`SCHED_NAME`,`CALENDAR_NAME`),
      KEY `IDX_QRTZ_T_G` (`SCHED_NAME`,`TRIGGER_GROUP`),
      KEY `IDX_QRTZ_T_STATE` (`SCHED_NAME`,`TRIGGER_STATE`),
      KEY `IDX_QRTZ_T_N_STATE` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
      KEY `IDX_QRTZ_T_N_G_STATE` (`SCHED_NAME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
      KEY `IDX_QRTZ_T_NEXT_FIRE_TIME` (`SCHED_NAME`,`NEXT_FIRE_TIME`),
      KEY `IDX_QRTZ_T_NFT_ST` (`SCHED_NAME`,`TRIGGER_STATE`,`NEXT_FIRE_TIME`),
      KEY `IDX_QRTZ_T_NFT_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`),
      KEY `IDX_QRTZ_T_NFT_ST_MISFIRE` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_STATE`),
      KEY `IDX_QRTZ_T_NFT_ST_MISFIRE_GRP` (`SCHED_NAME`,`MISFIRE_INSTR`,`NEXT_FIRE_TIME`,`TRIGGER_GROUP`,`TRIGGER_STATE`),
      CONSTRAINT `qrtz_triggers_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`) REFERENCES `qrtz_job_details` (`SCHED_NAME`, `JOB_NAME`, `JOB_GROUP`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='触发器和作业绑定';

    主要是对于触发器和作业的表的绑定。
    三、Quartz在ovirt中使用

  13. DBSchedulerUtilQuartzImpl的引用
  14. 注解

     @Inject
     private DBSchedulerUtilQuartzImpl scheduler;
  15. 通过构造方法注入

     DBSchedulerUtilQuartzImpl scheduler;
     
     public Constructor(){
       scheduler = Injector.get(DBSchedulerUtilQuartzImpl.class);
     }
  16. 调度任务的实现

    public class SnapshotTaskJob {
      @OnTimerMethodAnnotation("create_snapshot") //为定时器声明的名称,
     public void createSnapshot(String id) { //具体实现方法,该参数只能为基础类型、String类型
     ...逻辑实现,,,
     }
    }
  17. 调度的创建、修改、删除、暂停、恢复

    //创建  参数为 调度任务方法 方法名称,方法参数类型(仅支持基础类型以及String),方法参数值,cron表达式,开始时间,结束时间,优先级     方法返回jobName
    scheduler.scheduleACronJob(new SnapshotTaskJob(), "create_snapshot",
                     new Class[]{String.class},
                     new Object[]{snapshotDispatch.getId().toString()}, snapshotDispatch.getCronExpression(), nowDate, snapshotDispatch.getEndTime(), 5);
    
    //编辑  可在不修改任务名称下修改调度tigger  修改后如果原任务已暂停,则会重新启用该任务
    scheduler.rescheduleAJob(oldTriggerName, oldTriggerGroup, newTrigger);
    //暂停任务  jobId为创建调度返回的名称
    scheduler.pauseJob(jobId);
    //删除任务 删除该调度产生的所有信息
    scheduler.deleteJob(jobId);
    //恢复任务 恢复已经暂停的调度,                              
    scheduler.resumeJob(jobId); 
    //获取调度对象,可通过该方法调用quartz原生方法
    scheduler.getRawScheduler();                    
  18. 扩展方法

    • cron 表达式构建器
      backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/common/utils/CronBuilder.java

    可通过该方法快速创建cron表达式

    String = cron = CronBuilder.builder().hours(hour).minutes(minute).seconds(second).noYearBuild();
    • SchedulerUtil 调用封装
      backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/common/utils/SchedulerUtil.java

    可使用该方法创建各类cron表达式、判断当前任务是否存在
    # 总结

    1. 在ovirt使用quartz创建定时任务后,会将job信息、tigger信息存到数据库中,可通过外键关联,确保不会产生错误数据。
    2. quartz创建任务是,如果有结束时间,且在结束当天也有调度计划,quartz会在执行调度后将任务删除。

网站公告

今日签到

点亮在社区的每一天
去签到