概述
最近项目中使用了
spring
+Quartz定时任务、但是项目最近要集群部署、多个APP下如何利用Quartz 协调处理任务。
大家可以思考一下、现在有 A、B、C三个应用同时作为集群服务器对外统一提供服务、每个应用下各有一个Quartz、它们会按照既定的时间自动执行各自的任务。我们先不说实现什么功能,就说这样的架构其实有点像多线程。那多线程里就会存在“资源竞争”的问题,即可能产生脏读,脏写,由于三台 应用 里都有 Quartz,因此会存在重复处理 任务 的现象。
解决方案一:只在一台 应用 上装 Quartz,其它两台不装,这样集群就没有意义了。
解决方案二:使用其实Quartz自身可以实例化
数据库
的特性就可以解决问题
本方案优点:
1. 每台作为集群点的 应用上都可以布署 Quartz ;
2. Quartz 的 TASK ( 12 张表)实例化如数据库,基于数据库引擎及 High-Available 的策略(集群的一种策略)自动协调每个节点的 QUARTZ ,当任一一节点的 QUARTZ 非正常关闭或出错时,另几个节点的 QUARTZ 会自动启动;
3. 无需开发人员更改原已经实现的 QUARTZ ,使用 SPRING+ 类反射的机制对原有程序作切面重构;
解决方案:
1:去官网下载最新的 quartz 解压 在目录 docsdbTables 下就会找到 tables_mysql.sql 文件、建立数据库Quartz 并导入数据库。
2:生成 quartz.properties 文件,把它放在工程的 src 目录下 修改配置文件如下:
原因是在使用 quartz + spring 把 quartz 的 task 实例化进入数据库时,会产生: serializable 的错误,原因在于:
这个 MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的,因此在把 QUARTZ 的 TASK 序列化进入 数据库 时就会抛错。网上有说把 SPRING 源码 拿来,修改一下这个方案,然后再打包成 SPRING.jar 发布,这些都是不好的方法,是不安全的。
必须根据 QuartzJobBean 来重写一个自己的类 。
BootstrapJob. java : 引导Job,通过Spring容器获取任务的Job,根据注入的 target Job,该Job必须实现Job2接口
Job2.java:
重写 MethodInvokingJobDetailFactoryBean类 方法如下:
QuartzDeleteQueAction 任务类、一定要实现接口job2、只做参考。
4:配置 applicationContext-job. xml :
集群环境下测试:
三个个节点都带有 Quartz 任务,监控控制台、此时只有一台 quartz 在运行,另几个节点上的 quartz 没有运行。
此时手动 停掉那台运行 QUARTZ 过了 10分钟左右,另一个节点的 quartz 自动监测到了集群中运行着的 quartz 的 instance 已经 停掉 ,因此 quartz 集群会自动把任一台可用的 APP上启动起一个 quartz job 的任务。
至此 Quartz使用 集群策略已经ok,不用改原有代码,配置一下我们就可做到 Quartz的集群与自动错误冗余。
最后
以上就是迷人树叶为你收集整理的spring+Quartz集群的全部内容,希望文章能够帮你解决spring+Quartz集群所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复