Quartz 用 JobStores 对 Job、Trigger、calendar 和 Schduler 数据提供一种存储机制。Scheduler 应用已配置的 JobStore 来存储和获取到部署信息,并决定正被触发执行的 Job 的职责。所有的关于哪个 Job 要执行和以什么时间表来执行他们的信息都来自于 JobStore。本章就来看 Quartz 中可用的各种类型的 JobStore,和如何使用他们,以及哪一个能适应你的需求。

"罗马非一日建成"

道格拉斯.亚当斯,《宇宙环游指南》

一. Job 存储
在前面章节中,我们未曾花过任何时间来讨论 Scheduler 的 Job 和 Trigger 是保存在哪儿的。我们也许已经实现了,然而,当你停止了 Scheduler 后,那些有关哪些 Job 已经运行和哪些 Job 没有运行的信息就会丢失掉。实际上,所有的关于正在运行中的 Job 的信息也被销毁。
当程序被重启后,Trigger 和 Job 的信息被加回去,且所有的一切又都正常了。我们假定,有一个 Job 是安排为 5 PM 执行,然而 Scheduler 在这个时间之前的五分钟(4:55 PM) 时停掉了。如果你在 5:05 PM 时重新启动了 Scheduler 的话将会发生什么事情呢?Scheduler 还会记得要在 5 PM 触发这个 Job 的吗?答案就是看它是依赖于你使用的哪种类型的 JobStore,以及是如何对它配置的。
二. Quartz 中的 Job 存储
Quartz 支持对 Scheduler 信息的几种不同类型的存储机制。在 Quartz 中两种可用的 Job 存储类型是:
    · 内存(非持久化) 存储
    · 持久化存储
默认时,我们在前面几章的例子中已经使用了内存存储机制。两种类型都是用来服务于相同的目的:存储 Job 信息。然而他们各自是如何运作的,而且他们提供给 Scheduler 的功能是很不一样的。
·JobStore 接口
Quartz 为所有类型的 Job 存储提供了一个接口。这个接口位于 org.quartz.spi 包中,叫做 JobStore。所有的 Job 存储机制,不管是在哪里或是如何存储他们的信息的,都必须实现这个接口。
JobStore 可以列出太多的方法来,但是 JobStore 接口的 API  可归纳为下面几类:
    ·Job 相关的 API
    ·Trigger 相关的 API
    ·Calendar 相关的 API
    ·Scheduler 相关的 API
Quartz 的使用者几乎从不访问或是查看实现了 JobStore 接口的具体类;他们被 Quartz Scheduler 在运行期间内部使用来获取 Job 和 Trigger 信息。不过很值得练习一下,使你自己能熟悉每一种类型,这样你就能更好的理解这些为你所提供的存储机制,并有助于你在 Quartz 应用中选择一个正确的类型。
三. 使用内存来存储 Scheduler 信息
Quartz 直接可用的配置就是把 Job 和 Trigger 信息存储在内存中的。这个解释了为什么,对于前面章节中的例子,每次我们重启了 Quartz 应用程序后,Scheduler 的状态,包括 Job 和 Trigger 信息都丢失了。每回 Java 虚拟机(JVM) 关闭之后,它所占用的内存就释放回给了操作系统,因此任何关于 Job 和 Trigger 的信息都随 JVM 而丢失。
Quartz 的内存 Job 存储的能力是由一个叫做 org.quartz.simple.RAMJobStore 类提供了,当如我们所说,它实现了 JobStore 接口的。RAMJobStore 是 Quartz 的开箱即用的解决方案。对此,我们的意思是说,除非你改变了配置,否则在任何 Quartz 应用中都将使用 RAMJobStore。相比于其他的,使用这种 JobStore 可带来几个好处。
首先,RAMJobStore 是配置最简单的 JobStore:已给你配置好了的。当你下载并安装 Quartz 后,就已为你配置了使用 RAMJobStore 作为存储机制。你能在默认的 quartz.properties 文件中看到这个,如代码 6.1 所示。
代码 6.1. 没有其他配置时默认的 quartz.properties 文件

  1. # Default Properties file for use by StdSchedulerFactory
  2. # to create a Quartz Scheduler Instance, if a different
  3. # properties file is not explicitly specified.
  4. org.quartz.scheduler.instanceName = DefaultQuartzScheduler
  5. org.quartz.scheduler.rmi.export = false
  6. org.quartz.scheduler.rmi.proxy = false
  7. org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
  8. org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
  9. org.quartz.threadPool.threadCount = 10
  10. org.quartz.threadPool.threadPriority = 5
  11. org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
  12. org.quartz.jobStore.misfireThreshold = 60000
  13. org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

# 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
代码 6.1 中显示了包含在 Quartz 二进制包中的默认的 quartz.properties 文件。当你没在你自己的程序中引入一个 quartz.properties 文件,这个属性文件就会得到使用。你可以从默认的 quartz.properties 文件的最后一行看到,RAMJobStore 是名为 org.quartz.jobStore.class 的配置属性的默认值。甚至是未在 quartz.propterties 中设置 org.quartz.jobStore.class 属性时,RAMJobStore 也是默认所用的 JobStore。这是硬编码到 Scheduler 工厂初始化程序中的。
另一使用 RAMJobStore 是优点是它的速度。因为所有的 Scheduler 信息都保存在计算机内存中,访问这些数据随着电脑而变快。这儿不存在进程外的调用,没有数据库连,仅仅是原始而简单的内存访问。再也找不到比这更快的方式了。
·RAMJobStore 的 Job 易失性

你也许还记得在第四章,"部署 Job" 中讲过,Job 可以配置一个易失性属性。当这个易失性属性设置为 false,Job 将会在应用关闭之间持久化下来。这个属性对于用 RAMJobStore 时是不起作用的;那一行为是显式的为持久性的 JobStore 所保留的。
·配置 RAMJobStore
配置你的 Quartz 应用来使用 RAMJobStore 是非常简单的。假如你正用一个定制的 quartz.properties 文件,而不是来自于 Quartz JAR 文件中的,那么加上这行到你的属性文件中即可:
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
这就你要用 RAMJobStore 所要做的事情,正如我们所说的,没有比这更简单的了。
·加载 Job 到 RAMJobStore 中

既然 RAMJobStore 的目的是存储 Scheduler 信息,那么那些信息一开始是如何被加载到内存中的呢?你可以用两种方式加载 Job 信息。首先,你能硬编码你的 Job、Trigger、calendar 和 listener 到你的代码中。如第三章,"Hello,Quarz",第四章,"部署 Job" 所指出的,然而,这总是一件很危险的事情,因为这对于维护来说将是个梦魇。任何的改变,即使是微不足道的,都要修改代码然后重新编译。甚至是只改变触发的时间,也要改代码然后重编译。这没什么大不了的,你说呢?那也许对于小小的程序是这样的,但对于有大量的 Job 和 Trigger 的程序却成了一个大问题。
第二种途径是使用 JobInitializationPlugin,这会在第八章,"使用 Quartz 插件" 中详细讨论。这个 Quartz 插件使用一个 XML 文件来加载 Job、Trigger、Calendar 和其他你需要加载的东西。这种方式的优点是,当有改变时只需要对这个 XML 文件作改动,不用改代码,不用重编译,仅用一个文本编辑器。阅读第八章可获得关于 Quartz 插件更多的信息。
·RAMJobStore 的缺点
你要问了,"RAMJobStore 不能全是正面的,对吗?"。没错,确实如此。我们前面提到几个使用 RAMJobStore 的优点。现在,让我们来谈谈它的一个负面的地方:因为计算机的内存是易失性的,当你的 Quartz 程序被停止了,它会把内存释放回操作系统,当然了,伴随着存储在所释放内存里的别的内容就是这些部署信息了。
假如你的程序的 Scheduler 信息需要在程序重启之间能保持着,那么你需要看看持久性的 JobStore 了。

Job 存储和持久化 (第一部分)相关推荐

  1. Redis第一讲:相关的基础知识/数据类型/缓存的过期策略/双写一致性/内存存储和持久化

    Redis第一讲:相关的基础知识 摘要:本文是Redis(6.2.1)详解的第一讲,介绍Redis相关的基础知识,内存存储和持久化,Redis作缓存使用时的注意要点,常见的数据类型,缓存的过期策略,R ...

  2. IO流----向持久化存储进军的第一步

    目录 前言 正文 File类 概述 注意 递归 IO流 为什么 是什么 总之 缓冲流 怎么做 1,将模块目录下的1.png文件复制为2.png文件. 2.利用字符缓冲流写入文件并输出在控制台以及复制为 ...

  3. Android数据存储与持久化

    一.持久化技术简介 瞬时数据是指那些存储在内存当中,有可能会因为程序关闭或其他原因导致内存被回收而丢失的数据.这对于一些关键性的数据信息来说是绝对不能容忍的,谁都不希望自己刚发出去的一条微博,刷新一下 ...

  4. KV数据存储:持久化

    介质特性 由于内存的易失性,存储于内存的数据需要持久化来保证数据的安全.除了存储介质不同,本质上数据是可以在不同的存储介质中互相拷贝.内存极好的随机访问特性.磁盘seek极慢,良好的顺序读写性能:SS ...

  5. 应用存储和持久化数据卷:存储快照与拓扑调度(至天)

    本文将主要分享以下两方面的内容: 存储快照概念.使用与工作原理: 存储拓扑调度背景.概念.使用与工作原理. 基本知识 存储快照产生背景 在使用存储时,为了提高数据操作的容错性,我们通常有需要对线上数据 ...

  6. 应用存储和持久化数据卷:核心知识

    本次课程的分享主要围绕以下三个部分: K8s Volume 使用场景 PVC/PV/StorageClass 基本操作和概念解析 PVC+PV 体系的设计与实现原理 Volumes 介绍 Pod Vo ...

  7. 从零开始入门 K8s | 应用存储和持久化数据卷:存储快照与拓扑调度

    作者 | 至天 阿里巴巴高级研发工程师 一.基本知识 存储快照产生背景 在使用存储时,为了提高数据操作的容错性,我们通常有需要对线上数据进行 snapshot ,以及能快速 restore 的能力.另 ...

  8. 从零开始入门 K8s | 应用存储和持久化数据卷:核心知识

    作者 | 至天 阿里巴巴高级研发工程师 一.Volumes 介绍 Pod Volumes 首先来看一下 Pod Volumes 的使用场景: 场景一:如果 pod 中的某一个容器在运行时异常退出,被 ...

  9. Job 存储和持久化 (第五部分)

    十. 使用数据库存储 Scheduler 信息 ·加载 Job 到数据库中 在前面有一节,"使用内存存储 Scheduler 信息",我们谈到关于在使用 RAMJobStore 时 ...

最新文章

  1. iBATIS.NET DataMapper V1.3 Beta and DataAccess V1.7 Beta发布了
  2. websocket创建失败_SpringBoot2.2 实践WebSocket被不靠谱的百度搜索结果坑了多少人
  3. 计算机丢失qt4core.dll,qtcore4.;dll文件丢失。怎么办?
  4. 2020/Province_C_C++_A/F/成绩分析
  5. Effective C#:避免使用ICloneable接口
  6. TQ210 —— 点亮LED
  7. hadoop 多机全分布式安装步骤(虚拟机1master+2slave)
  8. IntelliJ IDEA母公司JetBrains遭美国调查,其是美国被大规模黑客攻击的源头?
  9. python telnetlib详解 执行循环命令_Python3+telnetlib实现telnet客户端
  10. (2)安装宝塔与docker及docker镜像下载加速
  11. 电涡流传感器9200-06-05-10-00本特利
  12. shiro+springMVC文档
  13. 基于深度学习的图像超分论文推荐
  14. 医学系统(一)医院常用的软件系统:PACS系统、HIS系统、RIS系统、LIS系统、CIS系统
  15. LaTeX中生成标题、摘要、关键词、目录方法以及自定义所需样式
  16. linux pdf中文乱码,英文乱码(乱码为方格之类的解决方法)
  17. CentOS安全运维检查命令
  18. DMS - 简介 Driver Monitor System
  19. Fastlane使用说明
  20. 视频怎么压缩变小?视频压缩变小的具体操作步骤

热门文章

  1. java面试算法总结_面试10大算法汇总——Java篇
  2. eigen 列拼接_R语言-强大的矩阵运算
  3. matlab使用load指令,科学网—matlab常用方法 - 陈超的博文
  4. java数字类型_Java数据类型
  5. Elasticseach 从零开始学习记录(四) - 整合springboot2.x
  6. 纠正Pandas中的缺失数据
  7. 通过GitHub Actions构建和部署Jekyll网站
  8. 初学者的持续集成和交付(DevOps)
  9. 为什么没有看到webcontent_王者荣耀之战坦路玩家心理:队友为什么不支援!我想要和射手换线...
  10. 战队不显示名字了_年仅17岁的新人选手!峡谷之巅1200分!被16家战队哄抢