Spring+Quartz 集群

这几天给Spring+Quartz的集群折腾得死去活来,google了无数页总算搞定,记下一些要点备之后使用。

单独的Quartz集群在http://unmi.blogjava.net/有Unmi翻译的Quartz Job Scheduling Framework一书作了详细说明,在此再也不重复。

Spring+Quartz不集群的方式google百度也能够搜索出来一大堆,一样略过。

要点1 在Spring中使用Quartz的高级配置
问题描述 Quartz集群仅能使用JDBC JobStore工做,须要在Spring中使用Quartz的高级配置
解决办法1.1 经过SchedulerFactoryBean的configLocation属性指定Quartz配置文件的位置。 java

Xml代码   收藏代码
  1. <bean id="quartzJobFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  2.     <property name="triggers">  
  3.         <list>  
  4.             <ref bean="clusterTesterJobScheduledTask" />  
  5.         </list>  
  6.     </property>  
  7.     <property name="configLocation" value="classpath:quartz.properties" />  
  8. </bean>  


解决办法1.2 经过SchedulerFactoryBean的quartzProperties属性直接配置。

要点2 NotSerializableException
问题描述 在将Quartz的Job持久化到数据库的过程当中产生NotSerializableException。详细异常信息为:
java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable: org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
解决办法 这是Spring的一个Bug,具体解决方案见http://jira.springframework.org/browse/SPR-3797,上面有解决的MethodInvokingJobDetailFactoryBean代码。

要点3 仍是NotSerializableException
问题描述 虽然MethodInvokingJobDetailFactoryBean的问题解决了,可是QuartzJob或者QuartzJob的属性没有实现Serializable接口(好比在QuartzJob中注入了DAO)。
解决办法3.1 若是是本身能够掌握的代码,能够为这些QuartzJob及其属性都加上实现Serializable接口。
解决办法3.2 编写一个实现Serializable接口,没有属性的QuartzJob,让它从Spring容器(ApplicationContext)中获取原来 的那个QuartzJob的Bean,再调用原来QuartzJob的方法解决问题。该方法的问题在于怎么获取ApplicationContext,如 果用ClassPathXmlApplicationContext,等因而另外建立了一个Spring容器(web.xml里面定义的是另一个)。
解决办法3.3 将原有的接口暴露,在Job中想办法远程调用该接口。
这三种办法各有好坏,如今也想不出其余更好的办法,先用这些顶着吧。

要点4 集群以后把其中一个Quartz服务停了,其余的也不接手工做
问题描述 集群以后,A节点执行了大多数任务,B节点大部分时间处于空闲,停掉A节点,B节点也不会接手工做。
解决办法 修改Quartz的配置,将每一个节点的org.quartz.scheduler.instanceId设置为不一样的值,或者都设置为AUTO。另外 org.quartz.jobStore.isClustered属性必须设为 true,org.quartz.jobStore.clusterCheckinInterval属性为集群中每次检查的时间间隔(按个人理解,应该差 很少等于一个服务器挂了以后,其余服务器接手的时间),单位为毫秒,默认值是15000。

要点5 MethodInvokingJobDetailFactoryBean几个属性的做用
问题描述 MethodInvokingJobDetailFactoryBean中concurrent和shouldRecover属性的做用
解释 concurrent为true,则容许一个QuartzJob并发执行,不然就是顺序执行。例如QuartzJob A执行时间为15秒,配置为每10秒执行一次;若是concurrent为true,则0秒的时候启动一次A,10秒的时候再启动一次A,20秒的时候再 启动一次A,无论前面启动的A有没有执行完;若是concurrent为false,则0秒的时候启动一次A,15秒的时候A执行完毕,再第二次启动A。
shouldRecover属性为true,则当Quartz服务被停止后,再次启动或集群中其余机器接手任务时会尝试恢复执行以前未完成的全部 任务。例如QuartzJob B,在每次00秒的时候启动,假如在03:00的任务执行完以后服务器1被停止,服务器2在05:15的时候才接手;若是shouldRecover属性 为true,则服务器2会尝试着补回原来在04:00和05:00的时候应该作的任务,若是shouldRecover属性为false,则服务器2只会 从06:00的时候再执行B。

附件是一个Demo,使用数据库为Oracle,建立数据库表的SQL脚本能够在Quartz的发行包(http://www.opensymphony.com/quartz/download.action)中\docs\dbTables目录下找到。数据库相关配置都在quartz.properties中,可根据实际须要自行修改。web

相关文章
相关标签/搜索