集群化Camel Quartz2路由行为不一致问题咨询
解决Spring+Camel+Quartz2集群下任务单节点执行问题(WebSphere7环境)
嘿,针对你这种基于Spring 4.0.3.RELEASE + Camel 2.13.4 + Quartz2 + Oracle11的应用,部署在WebSphere7(JDK1.6)垂直/水平集群环境中,要确保任务同一时间仅在一台机器运行的场景,我给你整理了一套经过验证的配置方案,结合你的环境做了适配:
一、Quartz核心集群配置(quartz.properties)
首先要配置Quartz的集群参数,让它基于Oracle数据库实现分布式锁,确保任务不重复执行。你可以把这个配置文件放在classpath下:
# 自动生成调度器实例ID,保证集群每个节点唯一 org.quartz.scheduler.instanceId=AUTO # 开启Quartz集群模式 org.quartz.jobStore.isClustered=true # 集群节点间的心跳检查间隔(单位:毫秒) org.quartz.jobStore.clusterCheckinInterval=20000 # 使用JDBC存储Job元数据,适配Oracle11 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate # 关联Spring中配置的数据源名称 org.quartz.jobStore.dataSource=quartzDS # Quartz在Oracle中创建的表前缀,要和你执行的建表脚本一致 org.quartz.jobStore.tablePrefix=QRTZ_ # 开启锁内获取触发器,避免集群竞争死锁 org.quartz.jobStore.acquireTriggersWithinLock=true # 使用标准行锁实现分布式同步 org.quartz.jobStore.lockHandler.class=org.quartz.impl.jdbcjobstore.StdRowLockSemaphore
二、Spring集成Quartz的配置
在Spring配置文件中,把Quartz和应用的数据源、WebSphere环境整合起来:
<!-- 引用WebSphere中配置的Oracle JNDI数据源 --> <bean id="quartzDS" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/OracleDS"/> <!-- 替换成你实际的JNDI名称 --> </bean> <!-- 配置Quartz调度器工厂,绑定集群配置和数据源 --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="dataSource" ref="quartzDS"/> <property name="quartzProperties" value="classpath:quartz.properties"/> <!-- 覆盖WebSphere默认线程池,避免容器线程冲突 --> <property name="taskExecutor"> <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="10"/> <property name="maxPoolSize" value="20"/> <property name="queueCapacity" value="50"/> </bean> </property> <!-- 启动时自动启动调度器 --> <property name="startScheduler" value="true"/> </bean>
三、Camel与Quartz2的集成配置
因为用到了Camel,需要把Quartz2组件和Spring的调度器绑定,同时开启Camel层面的集群支持:
<!-- Camel上下文配置 --> <camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring"> <!-- 配置Quartz2组件,关联Spring的调度器实例 --> <component id="quartz2"> <property name="scheduler" ref="schedulerFactoryBean"/> <!-- 开启Camel集群模式,确保路由任务仅单节点执行 --> <property name="cluster" value="true"/> </component> <!-- 示例定时路由:每天凌晨1点执行业务逻辑 --> <route id="dailyBusinessJob"> <from uri="quartz2://jobGroup/dailyJob?cron=0+0+1+*+*+?"/> <to uri="bean:dailyJobHandler?method=process"/> </route> </camelContext> <!-- 业务任务处理器,替换成你自己的实现类 --> <bean id="dailyJobHandler" class="com.yourcompany.business.DailyJobHandler"/>
四、关键注意事项
- 必须提前在Oracle中创建Quartz集群所需的表:Quartz官方提供了适配Oracle的建表脚本,注意表前缀要和配置中的
QRTZ_完全一致,脚本可以在Quartz的jar包中找到(路径:org/quartz/impl/jdbcjobstore/tables_oracle.sql)。 - WebSphere7的JNDI数据源要配置正确:确保数据源的权限足够创建、读写Quartz的表,同时要适配JDK1.6的驱动版本。
- 集群节点时钟严格同步:你已经做到了这一点,这是Quartz集群正常工作的基础,避免任务触发时间不一致导致的重复执行。
- 版本兼容性检查:Spring4.0.3.RELEASE + Camel2.13.4 + Quartz2的组合在JDK1.6下是兼容的,但要避免引入冲突的依赖(比如不要同时引入不同版本的Quartz或Spring核心包)。
- 垂直集群(同一机器多节点)的特殊处理:不要手动指定
instanceId,保持AUTO配置,确保每个节点生成唯一的实例ID,避免集群冲突。
内容的提问来源于stack exchange,提问作者Kabira Speaking
相关产品推荐
相关产品推荐

