quartz - JobStore存储方式

原创
2017/05/10 13:13
阅读数 1.2K

1. 前言

正如 quartz - 揭开面纱 这篇文章提到过的,jobstore是用来存储调度器需要的信息(触发时间,需要运行的job类等)的。在quartz框架的jobstore存储方式主要支持两种方式:RAMJobStore和JDBCJobStore。本次将重点讨论JDBCJobStore方式。

2. RAMJobStore

RAMJobStore 把数据保存在RAM内存中,如果应用意外奔溃或者服务器宕机了,那么调度器记录的一些待执行的任务数据将会丢失,也就是说不能在预定的时间执行指定的任务。要配置quartz使用RAMJobStore存储方式,只需要在配置文件中增加一项配置即可。

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore  

3. JDBCJobStore

JDBCJobStore,它以JDBC的方式在数据库中保存数据,由于数据需要经过网络和数据库存储,它的存取速度远不如RAMJobStore,但因为数据持久化的特点,使得在服务器宕机后,任务JOB得以恢复执行。JDBCJobStore 几乎适用于所有的数据库,支持 Oracle, PostgreSQL, MySQL, MS SQLServer, HSQLDB, 和DB2。

(1)在使用JDBCJobStore之前,我们需要在数据库中创建Quartz要使用的表,Quartz提供的建表文件在发布包的 “docs/dbTables” 目录下,本文使用的是MYSQL数据库,所以选用 tables_mysql_innodb.sql 。

(2)配置Quartz。配置文件中指定数据源和jobstore实现类。

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

org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL=jdbc:mysql://localhost:3306/quartz?characterEncoding=utf-8
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=123456
org.quartz.dataSource.myDS.maxConnections=5

(3)测试。本次实验将配置一个 每隔10秒钟执行一次,共执行5次的触发器,但把触发器注册到已经运行的调度器后,会在一秒钟后关闭调度器。然后隔一段时间后,再执行一段代码启动调度器。

JDBCStoreTest类,注册触发器,1秒钟后关闭调度器

public class JDBCStoreTest {
    private static final Logger logger = LoggerFactory.getLogger(JDBCStoreTest.class);

    public static void main(String[] args) throws SchedulerException, InterruptedException {
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
        schedulerFactory.initialize("quartz.properties"); //加载配置文件
        Scheduler scheduler = schedulerFactory.getScheduler();

        logger.info("Scheduler Name:" + scheduler.getSchedulerName());

        // 调度器开始工作
        scheduler.start();

        //创建一个job
        JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job_name_myjob").build();

        // 每隔10秒钟执行一次,共执行5次
        SimpleTrigger trigger = TriggerBuilder.newTrigger().startNow()
                .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(5, 10))
                .build();

        // job和trigger注册到scheduler
        scheduler.scheduleJob(job, trigger);

        Thread.sleep(1000);

        logger.info("关闭调度器ing...");
        // 关闭调度器,此时调度器将会经过shutting down -> paused -> shutdown complete三种状态
        scheduler.shutdown();

    }
}

此时,关闭调度器后,打开数据库查看quartz建立的表的数据,可以观察到数据库保存了任务和执行时间的一些信息。

JDBCStoreRebootTest类,该类将重启调度器。观察后台输出。

/**
 * 重启调度器
 */
public class JDBCStoreRebootTest {
    private static final Logger logger = LoggerFactory.getLogger(JDBCStoreRebootTest.class);

    public static void main(String[] args) throws SchedulerException, InterruptedException {
        StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
        schedulerFactory.initialize("quartz.properties"); //加载配置文件
        Scheduler scheduler = schedulerFactory.getScheduler();

        logger.info("Scheduler Name:" + scheduler.getSchedulerName());

        // 调度器开始工作
        scheduler.start();

        Thread.sleep(2 * 60 * 1000);

        logger.info("关闭调度器ing...");
        scheduler.shutdown();

    }
}

在之前的调度器关闭后1分钟,再重启调度器,可以在后台观察到,调度器在启动后,将会尝试恢复原有的任务,并开始执行之前已经过了触发时间的任务。

4. 相关资料

代码:https://git.oschina.net/thinwonton/QuartzDemo

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部