osgi环境下 quartz集群方案

首先是osgi环境要ok,可以参考之前的博客;

然后是quartz集群方案,这个比较绕;

最后是两者的结合,这个很蛋疼,基础不牢,搞了我一周

 

背景:集群环境下,quartz的任务会在每个节点上同时运行,这就乱套了,如果涉及到写数据库,还可能造成更大的麻烦,所以quartz在集群环境下需要考虑特殊解决方案。

解决方案1:集群上只部署一个quartz节点,绕开上述问题

解决方案2:一般是更新数据存储,在更新逻辑上加锁,或者增加业务逻辑代码,使得任务不被多次执行

解决方案3:把quartz的任务持久化到数据库中,每次任务触发,先到数据库中写入当前任务,并加锁,其他节点读取此任务或者写入此任务的时候,遇到锁,就不执行了,从而避免上述问题。

本博客介绍解决方案3 的执行思路

具体做法:

-之前在网上有前辈搞了个集群quartz方案,不过是基于普通web项目的,大致思路是,quartz把任务持久化入数据库,但是由于quartz的类或者是自己自定义的任务类没有实现 serializable接口,导致持久化失败。所以重写MethodInvokingJobDetailFactoryBean类,传入自己的任务类,任务类实现自定义的job接口,这个任务类在引用自己实际的定时任务,具体demo可以baidu或者google一下。由于osgi的类加载机制不同,所以这里需要注意一些类加载的问题

-基于osgi,最好把实际的定时任务单独搞成bundle,并发布出服务

-单独搞个quartz bundle,引用上面的服务,引用quartz包


   com.opensymphony.quartz
   com.springsource.org.quartz
   1.6.2
  

并且把这个工程打成bundle,并把org.quartz里面的包export出来,供你自己的http bundle import

-持久化问题,推荐使用plan的方式跑,不然会报莫名其妙的错误,然后需要自己为quartz单独配置数据源,不然会报无法获取trigger的异常

-注意,你自己的job和重写的MethodInvokingJobDetailFactoryBean类一定要和org.quartz包的类放在一个bundle里,不能放在http(就是有application-Context.xml)的那个bundle里,不然会循环依赖类的加载

然后就可以了

你可能感兴趣的:(原创)