quartz 持久化

上一篇写了quartz2.3.2的简单使用。但是Job的相关信息都是存在内存中的。对于一个持续定时任务比如执行100次一段逻辑,我们有时希望重新启动程序后应该将剩下的次数执行完,而不是重新执行100次。这时就需要持久化。

当然还有另一个原因,job持久化就意味着可以web管理job!

一、job持久化配置。resourses下新建quartz.properties内容如下

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

org.quartz.jobStore.misfireThreshold = 60000

##org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS

org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://39.100.116.73:3306/back_test
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = root
org.quartz.dataSource.qzDS.maxConnections = 10

属性说明:

1、org.quartz.scheduler.instanceName 可以是你喜欢的任何字符串。它用来在用到多个调度器区分特定的调度器实例。多个调度器通常用在集群环境中。目前我们的例子StdSchedulerFactory只有一个实例,我们就随便定一个标识即可

2、线程池相关配置:

1)threadCount 属性控制了多少个工作者线程被创建用来处理 Job。原则上是,要处理的 Job 越多,那么需要的工作者线程也就越多。threadCount 的数值至少为 1。Quartz没有限定你设置工作者线程的最大值,但是在多数机器上设置该值超过100的话就会显得相当不实用了,特别是在你的 Job 执行时间较长的情况下。这项没有默认值,所以你必须为这个属性设定一个值。

2)threadPriority 属性设置工作者线程的优先级。优先级别高的线程比级别低的线程更优先得到执行。threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1。这个属性的正常值是Thread.NORM_PRIORITY,为5。大多情况下,把它设置为5,这也是没指定该属性的默认值。

3)最后一个要设置的线程池属性是 org.quartz.threadPool.class。这个值是一个实现了 org.quartz.spi.ThreadPool 接口的类的全限名称。Quartz 自带的线程池实现类是 org.quartz.smpl.SimpleThreadPool,它能够满足大多数用户的需求。这个线程池实现具备简单的行为,并经很好的测试过。它在调度器的生命周期中提供固定大小的线程池。你能根据需求创建自己的线程池实现,如果你想要一个随需可伸缩的线程池时也许需要这么做。这个属性没有默认值,你必须为其指定值。

4) org.quartz.jobStrore.class 

持久化方式:org.quartz.impl.jdbcjobstore.JobStoreTX

Job信息内存存储时:org.quartz.simpl.RAMJobStore

如果使用持久化方式,需要先在数据库哪里执行数据库脚本建表。一般可以在github 项目目录下 docs/dbTables下。但是我使用的2.3.2版本中没发现这个目录。我使用的2.x其他版本目录中找了个脚本执行。是ok的。

5)呃呃呃呃呃,懒得写了,如果是持久化的,下面的配置相信一眼可以看出来在干什么。

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS

org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://39.100.116.73:3306/back_test
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = root
org.quartz.dataSource.qzDS.maxConnections = 10

2、随便写个持久化例子。

之前的例子在运行时都会在数据库中持久化存储,但是在此执行会报Job已存在错误。也就是对数据库中已存在的job怎样继续执行?怎样重新执行

1)已存在的,继续执行。就不要defaultScheduler.scheduleJob(job, build);

Scheduler defaultScheduler = null;
		try {

			defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
			logger.info("");
			
			JobDetail job = newJob(SimpleJob.class).withIdentity("job1", "group1").build();

			CronTrigger build = newTrigger().withIdentity("trigger1", "group1")
					.withSchedule(cronSchedule("0/2 * * * * ?")).build();
			if(!(defaultScheduler.checkExists(job.getKey()) && 
					defaultScheduler.checkExists(build.getKey()))){
				defaultScheduler.scheduleJob(job, build);
			}
			defaultScheduler.start();
			Thread.sleep(60000);
			//defaultScheduler.shutdown();
		} catch (SchedulerException e) {
			e.printStackTrace();
		} finally {
			if (defaultScheduler != null) {
				try {
					defaultScheduler.shutdown();
				} catch (SchedulerException e1) {
					e1.printStackTrace();
				}
			}
		}

2、重新运行。只展示下关键部分

if((defaultScheduler.checkExists(job.getKey()) 
				&& defaultScheduler.checkExists(trigger.getKey()))){
			defaultScheduler.deleteJob(job.getKey());
		}
		defaultScheduler.scheduleJob(job, trigger);
发布了78 篇原创文章 · 获赞 6 · 访问量 8526

猜你喜欢

转载自blog.csdn.net/MrBack/article/details/103948761
今日推荐