我正在尝试使用JDBCJobStore在集群模式下使用camel-quartz2组件。
quartz.properties 档案:
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.instanceName=JobCluster
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.dataSource=dsQuartzTest
org.quartz.jobStore.isClustered=true
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.dataSource.dsQuartzTest.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.dsQuartzTest.URL = jdbc:oracle:thin:pmuser@//10.13.13.10:1521/PDB1
org.quartz.dataSource.dsQuartzTest.user = pmuser
org.quartz.dataSource.dsQuartzTest.password = oracle
org.quartz.dataSource.dsQuartzTest.maxConnections = 10
camel-context.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Configures the Camel Context-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent">
<property name="propertiesFile" value="quartz.properties"/>
</bean>
<bean id="quartzBean" class="com.ubs.rbs.integration.QuartzBean"/>
<camel:camelContext xmlns="http://camel.apache.org/schema/spring">
<camel:route id="quartzRoute">
<camel:from uri="quartz2://tictac?cron=0+0/5+*+1/1+*+?+*"/>
<camel:setBody>
<camel:simple>
${header.triggerName} - ${header.fireTime}
</camel:simple>
</camel:setBody>
<camel:to uri="log:hello"/>
</camel:route>
<!--
<camel:route>
<camel:from uri="timer://updateQuartzRoute?repeatCount=1"/>
<camel:to uri="bean:quartzBean?method=reschedule(*,'quartzRoute')"/>
</camel:route>
-->
</camel:camelContext>
</beans>
当我第一次启动应用程序时,camel-quartz2组件使用适当的cron表达式调度作业,所有工作都正常。但是,当我停止应用程序的所有实例时,触发器仍然处于WAITING状态(对于集群来说可能是好的,因为组件无法判断最后一个实例何时停止,同样,我无法判断这一点是否相关,但没有集群它似乎没有问题)。因此,当我下次启动应用程序时,触发器已经存在且其设置将不适用。重要的是,当我更改cron表达式并重新启动所有实例时,quartz使用DB中的旧表达式,而不是组件的uri中的新表达式。
我找到了解决此问题的方法,使用其他路由(在上面的xml中注释掉)来重新安排自定义bean中的quartz,如下所示:
public class QuartzBean {
public void reschedule(CamelContext context, String quartzRouteId) throws Exception {
QuartzEndpoint endpoint = (QuartzEndpoint) context.getRoute(quartzRouteId).getEndpoint();
QuartzComponent component = endpoint.getComponent();
Scheduler scheduler = component.getScheduler();
Trigger oldTrigger = scheduler.getTrigger(endpoint.getTriggerKey());
TriggerBuilder tb = oldTrigger.getTriggerBuilder();
Trigger newTrigger = tb.withSchedule(CronScheduleBuilder.cronSchedule(endpoint.getCron())).build();
scheduler.rescheduleJob(oldTrigger.getKey(), newTrigger);
}
}
或者,我可以修改camel-quartz2组件,如下所示(org.apache.camel.component.quartz2.QuartzEndpoint#addJobInScheduler):
private void addJobInScheduler() throws Exception {
// Add or use existing trigger to/from scheduler
Scheduler scheduler = getComponent().getScheduler();
JobDetail jobDetail;
boolean triggerExisted = scheduler.getTrigger(triggerKey) != null;
if (triggerExisted) {
ensureNoDupTriggerKey();
}
jobDetail = createJobDetail();
Trigger trigger = createTrigger(jobDetail);
updateJobDataMap(jobDetail);
// Schedule it now. Remember that scheduler might not be started it, but we can schedule now.
Date nextFireDate = triggerExisted ? scheduler.rescheduleJob(triggerKey, trigger) : scheduler.scheduleJob(jobDetail, trigger);
if (LOG.isInfoEnabled()) {
LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
new Object[] {trigger.getKey(), trigger.getClass().getSimpleName(),
jobDetail.getJobClass().getSimpleName(), nextFireDate});
}
// Increase camel job count for this endpoint
AtomicInteger number = (AtomicInteger) scheduler.getContext().get(QuartzConstants.QUARTZ_CAMEL_JOBS_COUNT);
if (number != null) {
number.incrementAndGet();
}
jobAdded.set(true);
}
与项目存储库中的当前版本不同,如果触发器已经存在,我的版本总是会创建新的触发器并重新安排作业。
我的问题是:我错过了一些明显的东西吗?这个组件应该如何在这种情况下工作?我是否应该尝试更改组件本身,还是有更好的方法从外部更改其计划?
UPD:我从maven尝试了2.13.1版本,从源代码尝试了2.14.SNAPSHOT。
答案 0 :(得分:0)
Camel版本2.12.2及之前已知与Quartz相关的错误。如果不是,请给2.12.3及以上尝试。
答案 1 :(得分:0)
我已经提交了一个错误:https://issues.apache.org/jira/browse/CAMEL-7627以及补丁和单元测试。