浅析Quartz的集群配置(一)
收藏人:Rozdy    
2015-01-13 | 阅:1  转:22  
 |   来源
  |  分享 
 
 
 
  
 
 

1 基本信息

摘要:Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。其中集群配置一般比较复杂,那么在Quartz中如何配置它的集群特性呢?

作者:武玉厚

查看本文第二部分:http://gocom.primeton.com/modules/newbb/forumtopic19180_9963_40.htm

2 Quartz的集群配置

  Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。其中集群配置一般比较复杂,那么在Quartz中如何配置它的集群特性呢?

2.1 实现集群的基本原理

  目前Quartz最新版本是1.6.0。Quartz是通过借助关系数据库和JDBC作业存储来实现集群管理的。


 
1. 原理

  集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。目前集群只能工作在JDBC-Jobstore (JobStoreTX 或者JobStoreCMT)方式下,从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的(Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程)。

  负载平衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务(通过锁定),成为执行任务的节点。

  故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复(任务详细信息的"requests recovery"属性)的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行。

2. 集群管理用到的表

--任务详细信息表

  1. CREATE TABLE qrtz_job_details
  2. (
  3. JOB_NAME VARCHAR2(80) NOT NULL,
  4. JOB_GROUP VARCHAR2(80) NOT NULL,
  5. DESCRIPTION VARCHAR2(120) NULL,
  6. JOB_CLASS_NAME VARCHAR2(128) NOT NULL,
  7. IS_DURABLE VARCHAR2(1) NOT NULL,
  8. IS_VOLATILE VARCHAR2(1) NOT NULL,
  9. IS_STATEFUL VARCHAR2(1) NOT NULL,
  10. REQUESTS_RECOVERY VARCHAR2(1) NOT NULL, --可恢复标记
  11. JOB_DATA BLOB NULL,
  12. PRIMARY KEY (JOB_NAME,JOB_GROUP)
  13. );

--触发器与任务关联表

  1. CREATE TABLE qrtz_fired_triggers
  2. (
  3. ENTRY_ID VARCHAR2(95) NOT NULL,
  4. TRIGGER_NAME VARCHAR2(80) NOT NULL,
  5. TRIGGER_GROUP VARCHAR2(80) NOT NULL,
  6. IS_VOLATILE VARCHAR2(1) NOT NULL,
  7. INSTANCE_NAME VARCHAR2(80) NOT NULL,
  8. FIRED_TIME NUMBER(13) NOT NULL,
  9. STATE VARCHAR2(16) NOT NULL,
  10. JOB_NAME VARCHAR2(80) NULL,
  11. JOB_GROUP VARCHAR2(80) NULL,
  12. IS_STATEFUL VARCHAR2(1) NULL,
  13. REQUESTS_RECOVERY VARCHAR2(1) NULL, --可恢复标记
  14. PRIMARY KEY (ENTRY_ID)
  15. );

--调度器状态表

  1. TABLE qrtz_scheduler_state
  2. (
  3. INSTANCE_NAME VARCHAR2(80) NOT NULL, --调度器实例ID
  4. LAST_CHECKIN_TIME NUMBER(13) NOT NULL, --上次检查时间
  5. CHECKIN_INTERVAL NUMBER(13) NOT NULL, --检查时间间隔
  6. RECOVERER VARCHAR2(80) NULL, --恢复调度器
  7. PRIMARY KEY (INSTANCE_NAME)
  8. );

2.2 集群配置

  通过设置"org.quartz.jobStore.isClustered"属性为"true"来激活集群特性。在集群中的每一个实例都必须有一个唯一的"instance id" ("org.quartz.scheduler.instanceId" 属性), 但是应该有相同的"scheduler instance name" ("org.quartz.scheduler.instanceName"),也就是说集群中的每一个实例都必须使用相同的quartz.properties 配置文件。除了以下几种例外,配置文件的内容其他都必须相同:

? 不同的线程池大小,
? 不同的"org.quartz.scheduler.instanceId"属性值(这个可以很容易做到,设定为"AUTO"即可)。
? 注意: 永远不要在不同的机器上运行集群,除非他们的时钟是使用某种形式的同步服务(守护)非常有规律的运行(时钟必须在一分一秒内)来达到同步。还有: 永远不要触发一个非集群的实例,如果其他的实例正在同一个数据库表上运行。你将使你的数据严重腐蚀,出现非预期行为。
? 示例及详细配置说明,请参照附录Quartz配置文件说明。

3 附录

3.1 Quartz配置文件说明

3.1.1 Quartz配置文件基本说明

  文件名称:默认文件名称quartz.properties,可以通过更改系统属性“org.quartz.properties”来加载自定义的配置。
  格式:属性文件

3.1.2 Quartz配置文件详细说明

3.1.2.1 Scheduler主要属性的配置

  1. # Scheduler主要属性的一般定义模式如下:
  2. #
  3. # org.quartz.scheduler.instanceName = SCHED_NAME
  4. # org.quartz.scheduler.instanceId = INSTANCE_ID
  5. # org.quartz.scheduler.threadName = THREAD_NAME
  6. # org.quartz.scheduler.rmi.export = false
  7. # org.quartz.scheduler.rmi.proxy = false
  8. # org.quartz.scheduler.rmi.registryHost = localhost
  9. # org.quartz.scheduler.rmi.registryPort = 1099
  10. # org.quartz.scheduler.rmi.createRegistry = never
  11. # org.quartz.scheduler.userTransactionURL = USER_TX_LOCATION
  12. # org.quartz.scheduler.wrapJobExecutionInUserTransaction = JOBS_IN_USER_TX
  13. # org.quartz.scheduler.idleWaitTime = IDLE_WAIT_TIME
  14. # org.quartz.scheduler.dbFailureRetryInterval = DB_FAILURE_RETRY_INTERVAL
  15. # org.quartz.scheduler.classLoadHelper.class = CLASS_LOAD_HELPER_CLASS
  16. # org.quartz.context.key.SOME_KEY = SOME_VALUE

下面是具体说明:



3.1.2.2 线程池(ThreadPool)的配置

下面是具体说明:

  1. # 定制一个线程池的一般模式如下:
  2. #
  3. # org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
  4. # org.quartz.threadPool.threadCount = THREAD_COUNT
  5. # org.quartz.threadPool.threadPriority = THREAD_PRIO
  6. #
  7. # 简单线程池(SimpleThreadPool)的选项参数:
  8. #
  9. # org.quartz.threadPool.makeThreadsDaemons = DAEMON_THREADS
  10. # org.quartz.threadPool.threadsInheritGroupOfInitializingThread = INHERIT_GRP
  11. # org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = INHERIT_LDR
  12. #
  13. # or
  14. #
  15. # org.quartz.threadPool.class = com.mycompany.goo.FooThreadPool
  16. # org.quartz.threadPool.somePropOfFooThreadPool = someValue
  17. #

浅析Quartz的集群配置的更多相关文章

  1. quartz做集群配置较短的时间间隔会重复执行任务的问题

    quartz.properties org.quartz.jobStore.misfireThreshold = 60000 这个参数(单位为毫秒)设置了以后就是超时1min的就不执行,小于1min会 ...

  2. 定时组件quartz系列<二>quartz的集群原理

    1.基本信息:      Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2Se和J2EE应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它 来为执行一个作业而创建简单的或 ...

  3. Spring+quartz 实现定时任务job集群配置

    为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...

  4. Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群

    Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群 >>>>>>>>>>>>>> ...

  5. Spring+quartz 实现定时任务job集群配置【原】

    为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...

  6. 【淘淘】Quartz之集群利弊

    一.前言: 虽然单个Quartz实例能给予我们很好的任务job调度能力,但它不能满足典型的企业需求,如可伸缩性.高可靠性满足.假如你需要故障转移的能力并能运行日益增多的 Job,Quartz集群势必成 ...

  7. 基于redis的cas集群配置(转)

    1.cas ticket统一存储 做cas集群首先需要将ticket拿出来,做统一存储,以便每个节点访问到的数据一致.官方提供基于memcached的方案,由于项目需要,需要做计入redis,根据官方 ...

  8. 基于redis的cas集群配置

    1.cas ticket统一存储 做cas集群首先需要将ticket拿出来,做统一存储,以便每个节点访问到的数据一致.官方提供基于memcached的方案,由于项目需要,需要做计入redis,根据官方 ...

  9. 浅析Linux服务器集群系统技术

    浅析Linux服务器集群系统技术 目录 前言 常用的服务器集群 集群系统的优势 LVS集群的通用体系结构 为什么使用层次的体系结构 为什么是共享存储 可伸缩Web服务 前言 总结两篇技术文章,努力学习 ...

随机推荐

  1. 【译】Android系统简介—— Activity

    续上一篇,继续介绍Android系统.上一篇: [译]Android系统简介 本文主要介绍构建Android应用的一些主要概念: Activity Activity是应用程序中一个单独的有UI的页面( ...

  2. 关于C语言指针中的p++与p+i

    先看一组代码: #include <stdio.h> void main() { int i,*p,a[7]; p=a; for(i=0;i<7;i++) scanf("% ...

  3. Entity Framework Power Tools安装和使用

    Entity Framework Power Tools是一个由EntityFramework开发小组提供的工具,它可以从现有数据库生成Fluent款式的Code First代码. 大致来说,这个工具 ...

  4. iOS 进阶 第十三天(0414)

    0414 画线.圆和圆弧的第二种方法 5中方法画矩形: 第二种画图形的方法: 之前做的方法都是先把要画的元素缓存到图形上下文CGConteextRef中去,现在第二种方法也缓存到CGPath中去.其实 ...

  5. Interview-Increasing Sequence with Length 3.

    Given an array, determine whether there are three elements A[i],A[j],A[k], such that A[i]<A[j]< ...

  6. Regex.Match 方法

    Regex.Match 方法 在输入字符串中搜索正则表达式的匹配项,并将精确结果作为单个 Match 对象返回. 重载列表      (1) 在指定的输入字符串中搜索 Regex 构造函数中指定的正则 ...

  7. 合并2个dll成一个,好处你懂的

    步骤一:先下载微软的工具 ilmerge.exe 地址:http://www.microsoft.com/en-us/download/details.aspx?id=17630 步骤二:安装好之后 ...

  8. tomcat7.0.47 修改tomcat窗口名称

    最近使用的是 apache - tomcat 集群,为了方便管理上想要修改tomcat命令窗口的名字来区分不同的tomcat,我在网上找了些资料,顺便总结一下,方便自己,方便他人 修改如下: 找到to ...

  9. EXT--当defaultType与items的子组件默认xtype冲突时items的子组件的xtype为panel

    示例图 直接看下面示例代码: /** * 获取导入表单 * @returns {Ext.FormPanel} */ function getImportForm() { return new Ext. ...

  10. [C/CPP系列知识] Type difference of character literals 和 bool in C and C++

    C/C+中的每一个常亮(every literal)都是有类型的,例如10 就是int型的,因此siziof(10)和sizeof(int)是相同的,但是字符型常亮(‘a’)在C和C++中有不同的变量 ...