Quartz 基本概念

核心概念
1.Job:Job是任务执行的流程,是一个类
2.JobDetail:JobDetail是Job是实例,是一个对象,包含了该实例的执行计划和所需要的数据
3.Trigger:Trigger是定时器,决定任务何时执行
4.Scheduler:调度器,调度器接受一组JobDetail+Trigger即可安排一个任务,其中一个JobDetail可以关联多个Trigger
实例
1.初始化:
   
   
  1. Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
  2. scheduler.start();
当程序退出时,应该主动调用shutdown()方法关闭该调度器。
2.Job:
一个Job类需要实现org.quartz.Job接口,这个接口值需要实现一个方法即可:
   
   
  1. void execute(JobExecutionContext context) throws JobExecutionException
context是重要的上下文,可以访问到关联的JobDetail对象和本次触发的Trigger对象,以及在此之上设定的数据。
3.JobDetail:
可以使用JobBuilder来构建一个JobDetail对象:
   
   
  1. JobDetail job = JobBuilder.newJob(MyJob.class) // MyJob是我实现的Job类
  2. .withIdentity("myjob") // 可以给该JobDetail起一个id,便于之后的检索。也可以 .withIdentity("myjob", "group1")
  3. .requestRecovery() // 执行中应用发生故障,需要重新执行
  4. .storeDurably() // 即使没有Trigger关联时,也不需要删除该JobDetail
  5. .usingJobData("key1", "value1")
  6. .usingJobData("key2", "value2") // 以Key-Value形式关联数据
  7. .build();
Quartz因为考虑到有些任务不是幂等的,不可以多次重复执行,所以默认没有开启“requestRecovery”。当确认业务中允许一次任务执行两次的情况下,可以开启该选项,则任务肯定不会因为应用停止而漏调用,但缺点就是,有可能会重复调用。
每个JobDetail内都有一个Map,包含了关联到这个Job的数据,在Job类中,可以通过context取出该数据,进行业务流程处理。
4.Trigger:
可以使用TriggerBuilder来构建一个Trigger对象:
   
   
  1. Trigger trigger = TriggerBuilder.newTrigger()
  2. .forJob("myjob") // 关联上述的JobDetail
  3. .withIdentity("myjob-trigger1") // 给该Trigger起一个id
  4. .startAt(DateBuilder.futureDate(20, IntervalUnit.SECOND)) // 延迟20秒开始
  5. .withSchedule(SimpleScheduleBuilder.repeatMinutelyForever()) // 每分钟触发一次,无限循环
  6. .usingJobData("key3", "value3")
  7. .usingJobData("key4", "value4") // 以Key-Value形式关联数据
  8. .build();
5.设定:
因为上述的Trigger已经关联了JobDetail,可以使用
   
   
  1. scheduler.scheduleJob(trigger);
把这一组JobDetail和Trigger加载到调度器上,接下来就会按照计划执行Job任务。
6.配置文件:
配置文件不是必须的,Quartz对配置项都是有默认值的,当需要自定义的时候,可以在classpath路径下放一个quartz.properties文件,Quartz的StdSchedulerFactory在启动时会自动加载该配置文件。
比较值得关注的是这两个配置项:
   
   
  1. org.quartz.threadPool.threadCount=50
  2. org.quartz.scheduler.batchTriggerAcquisitionMaxCount=50
第一个配置项是线程池里的线程数,默认值是10,当执行任务会并发执行多个耗时任务时,要根据业务特点选择线程池的大小。
第二个配置是,当检查某个Trigger应该触发时,默认每次只Acquire一个Trigger,(为什么要有Acquire的过程呢?是为了防止多线程访问的情况下,同一个Trigger被不同的线程多次触发)。尤其是使用JDBC JobStore时,一次Acquire就是一个update语句,尽可能一次性的多获取几个Trigger,一起触发,当定时器数量非常大的时候,这是个非常有效的优化。当定时器数量比较少时,触发不是极为频繁时,这个优化的意义就不大了。
6.持久化
如果定时器在业务中属于关键数据,需要在故障重启后恢复状态,则需要把Quartz配置为持久化模式。默认情况下,所有定时任务和数据都保存在内存中,在应用重启后状态会消失。
JobStore决定了Quartz如何存储任务和触发器,默认值是org.quartz.simpl.RAMJobStore,我们需要把它配置为org.quartz.impl.jdbcjobstore.JobStoreTX,即可以使用JDBC数据源,把状态持久化到关系型数据库中。
用H2数据库进行举例,配置文件如下:
   
   
  1. org.quartz.dataSource.DATA_SOURCE_NAME.driver=org.h2.Driver
  2. org.quartz.dataSource.DATA_SOURCE_NAME.URL=jdbc:h2:quartz;MVCC=TRUE
  3. org.quartz.dataSource.DATA_SOURCE_NAME.user=sa
  4. org.quartz.dataSource.DATA_SOURCE_NAME.password=
  5. org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
  6. org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
  7. org.quartz.jobStore.dataSource=DATA_SOURCE_NAME
  8. # org.quartz.jobStore.useDBLocks=true
Quartz为了保证多线程下的一致性,使用了锁,但是使用了使用Lock表里的一行记录来模拟锁的形式来实现的,其实性能很糟糕,还不如使用默认的基于Java的Monitor锁的效果好,所以我注释掉了这个配置项。
之后,打开quartz-x.x.x.tar.gz包内的docs/dbTables文件夹内有各种数据库下的建表语句,直接在数据库中执行,把表先建好。
配置文件中增加上述对JobStore的设定后,代码不用修改一行,所有的任务和触发器已经是持久化的了,当应用停机重启后,错过的(misfire)任务和上次正在执行的(recovery)任务都会回复状态,如果JobDetail指定了requestRecovery,上次执行中,但没有执行完毕的任务会重新执行一遍。

注意事项:
>  一个任务JOB可以添加多个Trigger 但是一个Trigger只能绑定一个JOB 这点需要注意。
>  在用JobBuilder创建JobDetail的时候,有一个storeDurably()方法,可以在没有触发器指向任务的时候,使用 sched.addJob(job, true) 将任务保存在队列中了。而后使用 sched.scheduleJob 触发。如果不使用  storeDurably ,则在添加 Job 到引擎的时候会抛异常,意思就是该 Job 没有对应的 Trigger。
要求cluster上所有的node的时间应该是一样的。


 
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
中文版目录总汇及内容提要 第一章. 企业应用中的作业调度 内容提要:什么是作业调度,作业调度为什么说是重要的,企业应用中的作业调度,非企业应用中的作业调度,作业调度与工作流,关于作业调度其他可选择方案 第二章. Quartz 起步 内容提要:本章对 Quartz 框架一个快速的入门介绍,同时也大略指导你从哪里下载,构建和安装这个框架 第三章. Hello Quartz (第一部分) 内容提要:建立 Hello Quartz 工程,并创建一个 Quartz Job 类 ScanDirectoryJob. 第三章. Hello Quartz (第二部分) 内容提要:创建一个 Quartz Scheduler,关联上一个 Quartz Trigger 以编程方式调度前面编写的 ScanDirectoryJob 运行。 第三章. Hello Quartz (第三部分) 内容提要:通过配置 quartz.properties、quartz_jobs.xml 以声明的方式调度 ScanDirectoryJob 运行。 第三章. Hello Quartz (第四部分) 内容提要:让我们最后简单讨论打包一个用到了 Quarts 框架的应用程序的流程,需要依赖于哪些包,也以此来结束本章的内容。 第四章. 部署 Job (第一部分) 内容提要:介绍 Scheduler 和 SchedulerFactory 有哪些类型、SchedulerFactory 的关键 API 方法;以及如何通过 java.util.Properties 实例或默认 quartz.properties 文件创建 Scheduler。 第四章. 部署 Job (第二部分) 内容提要:如何管理 Scheduler(启动、停止、Standby 模式)。还介绍了 Job、JobExecutionContext、JobDetail、JobDataMap,及如何访问 JobDataMap 中的数据。有状态和无状态的 Job。 第四章. 部署 Job (第三部分) 内容提要:Job 的易失性、持久性和可恢复性,如何从 Scheduler 中移除、中断 Job。Quartz 已为我们提供了哪些 Job。最后是 Java 线程的简单介绍。 第四章. 部署 Job (第四部分) 内容提要:线程在 Quartz 中的用法,主处理线程:QuartzSchedulerThread 和 Quartz 工作者线程。Quartz Trigger 和 Calendar 各有哪些类型和如何使用。 第五章. Cron 触发器及相关内容 (第一部分) 内容提要:引入 Quartz CronTrigger 及简单使用 CronTrigger 来部署一个 Job 第五章. Cron 触发器及相关内容 (第二部分) 内容提要:详细介绍了 cron 表达式的格式和像 , - * ? / L W C # 特殊符号的使用 第五章. Cron 触发器及相关内容 (第三部分) 内容提要:CronTrigger 使用起(startTime) 迄(endTime) 日期的使用。TriggerUtils 简单方便的创建 Trigger。应用 JobInitializationPlugin 在 quartz_jobs.xml 配置文件中写 Cron 表达式。 第五章. Cron 触发器及相关内容 (第四部分) 内容提要:Cron 表达式 Cookbook,列举了各种 Cron 表达式的写法和意义,有助于更好的理解 Cron 表达式;还用了 TriggerUtils 创建了一个即刻触发的 Trigger。 第六章. Job 存储和持久化 (第一部分) 内容提要:介绍 Quartz 中的 Job 存储,JobStore 接口相关 API 方法。使用 RAMJobStore 来实现 Job 存储及它的优缺点。 第六章. Job 存储和持久化 (第二部分) 内容提要:使用持久性的 JobStore,可用类型 JobStoreTX 和 JobStoreCMT。持久性 JobStore 是通过数据库来完成的,哪可支持哪些数据及需要创建些什么表。 第六章. Job 存储和持久化 (第三部分) 内容提要:使用和配置 JobStoreTX,需要为不同数据库平台指定不同的驱动代理( DriverDelegate),和 quartz.properties 中与 JobStoreTX 相关配置说明。 第六章. Job 存储和持久化 (第四部分) 内容提要:为 JobStoreTX 通过在 quartz.properties 配置来创建数据源,并在 Scheduler 中使用数据源 第六章. Job 存储和持久化 (第五部分

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

catoop

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值