这几天给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配置文件的位置。

  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中,可根据实际需要自行修改。

Spring+Quartz 集群的更多相关文章

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

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

  2. Spring+quartz集群解决多服务器部署定时器重复执行的问题

    一.问题描述 Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了.不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行. 二.解决方案 Spr ...

  3. Spring+Quartz集群环境下定时调度的解决方案

    集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...

  4. 序列化人人网框架下的DAO?也就是在Spring下序列化DAO的问题(spring+quartz集群下)

    人人网框架地址:http://code.google.com/p/paoding-rose/ 问题发生: 用Quartz作集群时用JobDataMap传递DAO,提示DAO未序列化,可框架的DAO为接 ...

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

    原 来配置的Quartz是通过spring配置文件生效的,发现在非集群式的服务器上运行良好,但是将工程部署到水平集群服务器上去后改定时功能不能正常运 行,没有任何错误日志,于是从jar包.JDK版本. ...

  6. spring boot + quartz 集群

    spring boot bean配置: @Configuration public class QuartzConfig { @Value("${quartz.scheduler.insta ...

  7. Spring集成quartz集群配置总结

    1.spring-quartz.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE be ...

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

    最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要 ...

  9. Quartz Spring分布式集群搭建Demo

    注:关于单节点的Quartz使用在这里不做详细介绍,直接进阶为分布式集群版的 1.准备工作: 使用环境Spring4.3.5,Quartz2.2.3,持久化框架JDBCTemplate pom文件如下 ...

随机推荐

  1. TeamViewer的下载地址,低调低调

    https://github.com/cary-zhou/TeamViewer13-Crack

  2. java8 - Optional

    mport java.util.Optional; import org.junit.Test; /* * 一.Optional 容器类:用于尽量避免空指针异常 * Optional.of(T t) ...

  3. 【转载】Node.js 教程(菜鸟教程系列)

    很好的一篇教程:Node.js 教程 简单做下笔记 概述 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立 ...

  4. c++模板与泛型编程基础

    (1)定义函数模板(function template) 函数模板是一个独立于类型的函数,可以产生函数的特定类型版本. // implement strcmp-like generic compare ...

  5. Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException

    org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean ...

  6. ref:如何将自定义异常的信息显示在jsp页面上

    ref:https://blog.csdn.net/tao_ssh/article/details/53486449 在项目中,经常会抛出异常,输出比较友好的信息来提示用户,并指导用户行为.大体思路: ...

  7. 深入理解SQL的四种连接,左外连接,右外连接,内连接,全连接

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

  8. firewalld启动问题

    问题 在查看或启动firewalld服务时,提示"Warning: firewalld.service changed on disk. Run 'systemctl daemon-relo ...

  9. Django基础-Lesson1

    web框架概念 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统. 对于所有的Web应用,本质上其实就是一个socket服务端, ...

  10. OpenStack Keystone V3 简介

    Keystone V3 简介 Keystone 中主要涉及到如下几个概念:User.Tenant.Role.Token.下面对这几个概念进行简要说明. User:顾名思义就是使用服务的用户,可以是人. ...