这几天给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. Visual Studio 2017 发布 附带下载地址

    链接: https://pan.baidu.com/s/1kFjGwyj5HwabvmJKiyLF_g 提取码: 关注公众号[GitHubCN]回复获取    winform框架源码-Devexpre ...

  2. 关键字final和override

    final关键字 限制某个类或结构体不能被继承 直接对类声明: class A final{}; class B : public A {}; 或这类内有final函数,类可以被继承,但是final函 ...

  3. linux如何连接移动硬盘

    下载第三方插件的地方: http://www.tuxera.com/community/open-source-ntfs-3g/ 这是具体教程: http://hellopyl.blog.51cto. ...

  4. 002 python语法入门

    一:基本数据类型知识点 1.基本数据类型 Number 数字 String 字符串 Bool 布尔 List 列表 Tuple 元组 Set 集合 Dictionary字典 2.分类 )标准的pyth ...

  5. Two-stage rotation animation is deprecated. This application should use the smoother single-stage an

    问题出在rootViewController同时包含UITabBarController和UINavigationController. 几经尝试,最后发现,在设置为window.rootViewCo ...

  6. 神经网络一(用tensorflow搭建简单的神经网络并可视化)

    import tensorflow as tf import numpy as np import matplotlib.pyplot as plt #创建一个input数据,-1到1之间300个数, ...

  7. JDK源码分析(二)——LinkedList

    目录 LinkedList LinkedList继承结构 LinkedList内部类Node LinkedList成员属性 LinkedList构造方法 重要方法 Deque方法的实现 遍历 总结 L ...

  8. nova event

    nova处理neutron发送过来的event事件.暂时追踪nova event部分代码 tail -f /var/log/nova/nova-api.log  下面就是一个事件  Creating ...

  9. grunt自动化

    1.安装模块 npm install grunt -g npm install grunt-cli -g #! --save-dev 既会把模块安装到项目node_modules下,也会安装到依赖文件 ...

  10. 【WIN10】判斷程序運行在哪個平台

    其中的一個方法是: string x = AnalyticsInfo.VersionInfo.DeviceFamily; 判斷 x  的值,有”Windows.Mobile“,”Windows.Des ...