(4) Spring中定时任务Quartz集群配置学习

原 来配置的Quartz是通过spring配置文件生效的,发现在非集群式的服务器上运行良好,但是将工程部署到水平集群服务器上去后改定时功能不能正常运 行,没有任何错误日志,于是从jar包、JDK版本、cronExpression到服务器类型,甚至查到了服务器操作系统的类型,都没能找到解决的办 法,后来才知道是集群惹的祸!

详细步骤如下:

1、 按照Quartz集群工作原理

图:表示了每个节点直接与数据库通信,若离开数据库将对其他节点一无所知

在数据库中建表。建表模版在Quartz包下docs/dbTables下,选择相应的数据库和版本即可。ORACLE的11个Table列表如下:

QRTZ_JOB_LISTENERS:存储有关已配置的 JobListener 的信息

  •  JOB_NAME
  •  JOB_GROUP
  •  JOB_LISTENER

QRTZ_TRIGGER_LISTENERS:存储已配置的 TriggerListener 的信息

QRTZ_FIRED_TRIGGERS:存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息

QRTZ_PAUSED_TRIGGER_GRPS:存储已暂停的 Trigger 组的信息

QRTZ_SCHEDULER_STATE:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态

  •  INSTANCE_NAME 之前配置文件中org.quartz.scheduler.instanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字
  •  LAST_CHECKIN_TIME:上次检查时间
  •  CHECKIN_INTERVAL :检查间隔时间

QRTZ_LOCKS:存储程序的悲观锁的信息(假如使用了悲观锁)

QRTZ_SIMPLE_TRIGGERS:存储简单的Trigger,包括重复次数,间隔,以及已触的次数

  •  TRIGGER_NAME :qrtz_triggers表trigger_name的外键
  •  TRIGGER_GROUP:qrtz_triggers表trigger_group的外键
  •  REPEAT_COUNT :重复次数
  •  REPEAT_INTERVAL:时间间隔
  •  TIMES_TRIGGERED:触发次数

QRTZ_CRON_TRIGGERS:存储cron表达式表

  •  TRIGGER_NAME :qrtz_triggers表trigger_name的外键
  •  TRIGGER_GROUP:qrtz_triggers表trigger_group的外键 
  •  CRON_EXPRESSION:cron表达式
  •  TIME_ZONE_ID :时区

QRTZ_TRIGGERS:保存trigger信息

  •  TRIGGER_NAME :trigger的名字,该名字用户自己可以随意定制,无强行要求
  •  TRIGGER_GROUP:所属组的名字,该名字用户自己随意定制,无强行要求
  •  JOB_NAME :qrtz_job_details表job_name的外键
  •  JOB_GROUP :qrtz_job_details表job_group的外键
  •  IS_VOLATILE 0
  •  DESCRIPTION
  •  NEXT_FIRE_TIME
  •  PREV_FIRE_TIME
  •  PRIORITY 5
  •  TRIGGER_STATE :当前trigger状态,设置为ACQUIRED,如果设置为WAITING,则job不会触发
  •  TRIGGER_TYPE:触发器类型,使用cron表达式
  •  START_TIME
  •  END_TIME
  •  CALENDAR_NAME
  •  MISFIRE_INSTR
  •  JOB_DATA

QRTZ_JOB_DETAILS:保存job详细信息,该表需要用户根据实际情况初始化

  •  JOB_NAME :集群中job的名字,该名字用户自己可以随意定制,无强行要求
  •  JOB_GROUP :集群中job的所属组的名字,该名字用户自己随意定制,无强行要求 
  •  DESCRIPTION
  •  JOB_CLASS_NAME:集群中个note job实现类的完全包名,quartz就是根据这个路径到classpath找到该job类 
  •  IS_DURABLE:是否持久化,把该属性设置为1,quartz会把job持久化到数据库中
  •  IS_VOLATILE
  •  IS_STATEFUL
  •  REQUESTS_RECOVERY
  •  JOB_DATA :一个blob字段,存放持久化job对象

QRTZ_CALENDARS:以 Blob 类型存储 Quartz 的 Calendar 信息

QRTZ_BLOB_TRIGGERS:作为 Blob 类型存储(用于 Quartz 用户用 JDBC创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)

  •  TRIGGER_NAME :qrtz_triggers表trigger_name的外键
  •  TRIGGER_GROUP:qrtz_triggers表trigger_group的外键 
  •  BLOB_DATA

2、 配置数据库连接池,如果spring已经配置则不需要再另行配置,只需在后面配置的applicationContext-quartz.xml引入即可。

applicationContext.xml:

<bean id="propertyConfigurer"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location">

<value>classpath:dataConfig.properties</value>

</property>

</bean>

<bean id="ds34" class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close">

<property name="driverClassName">

<value>${ds34.driver}</value>

</property>

<property name="url">

<value>${ds34.url}</value>

</property>

<property name="username">

<value>${ds34.username}</value>

</property>

<property name="password">

<value>${ds34.password}</value>

</property>

<property name="maxActive" value="5"></property>

<property name="maxIdle" value="20"></property>

<property name="maxWait" value="50"></property>

<property name="defaultAutoCommit" value="true"></property>

</bean>

dataConfig.properties:

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver

jdbc.url=jdbc:oracle:thin:@localhost:1521:test

jdbc.username=test

jdbc.password=test

3、 配置quartz.properties

v org.quartz.scheduler.instanceName属性可为任何值,用在 JDBC JobStore 中来唯一标识实例,但是所有集群节点中必须相同。

v org.quartz.scheduler.instanceId 属性为 AUTO即可,基于主机名和时间戳来产生实例 ID。

v org.quartz.jobStore.class属性为 JobStoreTX,将任务持久化到数据中。因为集群中节点依赖于数据库来传播 Scheduler 实例的状态,你只能在使用 JDBC JobStore 时应用 Quartz 集群。这意味着你必须使用 JobStoreTX 或是 JobStoreCMT 作为 Job 存储;你不能在集群中使用 RAMJobStore。

v org.quartz.jobStore.isClustered 属性为 true,你就告诉了 Scheduler 实例要它参与到一个集群当中。这一属性会贯穿于调度框架的始终,用于修改集群环境中操作的默认行为。

v org.quartz.jobStore.clusterCheckinInterval 属性定义了Scheduler 实例检入到数据库中的频率(单位:毫秒)。Scheduler 检查是否其他的实例到了它们应当检入的时候未检入;这能指出一个失败的 Scheduler 实例,且当前 Scheduler 会以此来接管任何执行失败并可恢复的 Job。通过检入操作,Scheduler 也会更新自身的状态记录。clusterChedkinInterval 越小,Scheduler 节点检查失败的 Scheduler 实例就越频繁。默认值是 15000 (即15 秒)。

quartz.properties:

##Quartz 调度任务所需的配置文件

##org.quartz.scheduler.instanceName属性可为任何值,用在 JDBC JobStore 中来唯一标识实例,但是所有集群节点中必须相同。

org.quartz.scheduler.instanceName = HumsScheduler

##org.quartz.scheduler.instanceId 属性为 AUTO即可,基于主机名和时间戳来产生实例 ID。

org.quartz.scheduler.instanceId = AUTO

orgorg.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属性为 JobStoreTX,将任务持久化到数据中。

##因为集群中节点依赖于数据库来传播 Scheduler 实例的状态,你只能在使用 JDBC JobStore 时应用 Quartz 集群。

##这意味着你必须使用 JobStoreTX 或是 JobStoreCMT 作为 Job 存储;你不能在集群中使用 RAMJobStore。

orgorg.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

orgorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.maxMisfiresToHandleAtATime=10

##org.quartz.jobStore.isClustered 属性为 true,你就告诉了 Scheduler 实例要它参与到一个集群当中。

##这一属性会贯穿于调度框架的始终,用于修改集群环境中操作的默认行为。

org.quartz.jobStore.isClustered = true

##org.quartz.jobStore.clusterCheckinInterval 属性定义了Scheduler 实例检入到数据库中的频率(单位:毫秒)。

##Scheduler 检查是否其他的实例到了它们应当检入的时候未检入;这能指出一个失败的 Scheduler 实例,且当前 Scheduler 会以此来接管任何执行失败并可恢复的 Job。

##通过检入操作,Scheduler 也会更新自身的状态记录。clusterChedkinInterval 越小,Scheduler 节点检查失败的 Scheduler 实例就越频繁。默认值是 15000 (即15 秒)。

org.quartz.jobStore.clusterCheckinInterval = 20000

4、 配置applicationContext-quartz.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="dataSource">

<ref bean="dataSource"/>

</property>

<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>

<property name="configLocation" value="classpath:quartz.properties"/>

<property name="triggers">

<list>

<ref bean="trigger1"/>

<!--

<ref bean="trigger2"/>

-->

</list>

</property>

</bean>

<bean id="jobDetail1" class="frameworkx.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="simpleService"/>

<property name="targetMethod" value="testMethod1"/>

<property name="shouldRecover" value="true"/>

</bean>

<bean id="trigger1" class="org.springframework.scheduling.quartz.CronTriggerBean">

<property name="jobDetail" ref="jobDetail1"/>

<property name="cronExpression" value="* 0/1 * ? * * *"/>

</bean>

<!--

<bean id="jobDetail2" class="frameworkx.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="simpleService"/>

<property name="targetMethod" value="testMethod2"/>

<property name="shouldRecover" value="true"/>

</bean>

<bean id="trigger2" class="org.springframework.scheduling.quartz.SimpleTriggerBean">

<property name="jobDetail" ref="jobDetail2"/>

<property name="startDelay" value="1"/>

<property name="repeatCount" value="100"/>

<property name="repeatInterval" value="1000"/>

</bean>

-->

</beans>

5、 配置Job任务注意:加入定时任务有两种方式:

① 继承QuartzJobBean的类,重写executeInternal(),详细写法:

<bean id="jobDetail1" class="org.springframework.scheduling.quartz.JobDetailBean">
 <property name="jobClass">
 <value>继承QuartzJobBean的类的引用</value>
 </property>
</bean>



org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
指定类和方法,但是直接使用会报java.io.NotSerializableException异常,一般用网上流传的(需要将两个类copy到自己
的工程下,要有springJAR包,Job需要持久化到数据库中,SimpleService必须实现
Serializable)frameworkx.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean。
详细写法:

<bean id="jobDetail1" class=" 工程里MethodInvokingJobDetailFactoryBean的路径.MethodInvokingJobDetailFactoryBean">

<property name="targetObject" ref="simpleService"/>

<property name="targetMethod" value="testMethod1"/>

<property name="shouldRecover" value="true"/>

</bean>

6、 配置到spring配置文件,自动调度任务。

<import resource="applicationContext-quartz.xml"></import>

7、 测试用例

public class MainTest {

/**

* @param args

*/

public static void main(String[] args) {

ApplicationContext springContext = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext.xml"});

}

}

时间: 2024-09-30 10:59:36

(4) Spring中定时任务Quartz集群配置学习的相关文章

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

为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真实结果的3倍,那对银行来说是无法想象的,完全不可接受. 集群定时任务工作原理 所以为了解决以上问题,每个server把将要及正在运行的job所有状态都即时同步到中央数据库,然后再次触发调用时从数据库中分析是否已有别的server正在运行相同job (同名同定时时间点的job属于相当job),如果相同

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

Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 蕃薯耀 2016年7月7日 09:06:09 星期四 http://fanshuya

项目中使用Quartz集群分享--转载

项目中使用Quartz集群分享--转载 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享  一:CRM对定时任务的依赖与问题  二:什么是quartz,如何使用,集群,优化  三:CRM中quartz与Spring结合使用 1:CRM对定时任务的依赖与问题  1)依赖  (1)每天晚上的定时任务,通过sql脚本 + crontab方式执行 Xml代码   #crm 0 2 * * * /opt/***/javafiles/***/shell/***_dail

Quartz集群配置

Quartz集群配置(100%成功) 先看看quartz的持久化基本介绍: 引用 1 大家都清楚quartz最基本的概念就是job,在job内调用具体service完成具体功能,quartz需要把每个job存储起来,方便调度,quartz存储job方式就分三种,我们最常用的也是quartz默认的是RAMJobStore,RAMJobStore顾名思义就是把job的相关信息存储在内存里,如果用spring配置quartz的job信息的话,所有信息是配置在xml里,当spirng context启动

转载 Tomcat集群配置学习篇-----分布式应用

Tomcat集群配置学习篇-----分布式应用 现目前基于javaWeb开发的应用系统已经比比皆是,尤其是电子商务网站,要想网站发展壮大,那么必然就得能够承受住庞大的网站访问量:大家知道如果服务器访问量过大,就会出现服应用务器崩溃的情况,这个时候怎么办,难道就只能去重启服务器吗?好,如果是一般的小型公益网站到也无所谓,但如果是比如像大型航空公司售票等电子商务网站,每天每小时都有大量的订单业务,如果这些售票系统一旦崩溃后,再去重启,这些时间和客户的损失就直接会影响到航空公司的利益,这些损失如何去避

spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】

最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要的表导入数据库 官网上有不同数据库的脚本,找到对应的,导入即可 3. java 代码 将quartz 的相关配置文件,配置为暴露bean,方便后期引用. 有一处关键的地方,就是注入spring 上下文,也可以算是一个坑.如果,不注入spring 上下文,那么新添加的定时任务job,是新new 的一个

spring quartz 集群配置

Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. 在项目中有大量的后台任务需要调度执行,如构建索引.统计报表.周期同步数据等等,要求任务调度系统具备高可用性.负载均衡特性,使用Quartz 会很方便. 下文是spring和quartz进行整合,同时支持集群部署.quartz集群的支持是通过数据库进行任务调度的感知. 1.使用的版本情况:spring

Spring中使用Quartz之MethodInvokingJobDetailFactoryBean配置任务

Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz. Spring中使用Quartz的3种方法(MethodInvokingJobDetailFactoryBean,implements Job,extends QuartzJobBean): 以下为在Spring中怎样配置Quartz: 首先写一个被调度的类: package com.test.quartz; public class QuartzJob { public void work() { System

Tomcat集群配置学习篇-----分布式应用

现目前基于javaWeb开发的应用系统已经比比皆是,尤其是电子商务网站,要想网站发展壮大,那么必然就得能够承受住庞大的网站访问量:大家知道如果服务器访问量过大,就会出现服应用务器崩溃的情况,这个时候怎么办,难道就只能去重启服务器吗?好,如果是一般的小型公益网站到也无所谓,但如果是比如像大型航空公司售票等电子商务网站,每天每小时都有大量的订单业务,如果这些售票系统一旦崩溃后,再去重启,这些时间和客户的损失就直接会影响到航空公司的利益,这些损失如何去避免呢. 别担心,不管是目前IBM的webSphe