我想设置带有聚类选项的camel-quartz2调度程序。
这是我目前的编码/配置:
package com.foo.bar.quartz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan({"com.foo.bar.quartz.camel"})
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
package com.foo.bar.quartz;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class ApplicationWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
application
.showBanner(false)
.sources(Application.class);
return application;
}
}
package com.foo.bar.quartz.camel;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CamelScheduler extends RouteBuilder {
@Override
public void configure() throws Exception {
from("quartz2://group1/trigger1?cron=0/2+*+*+*+*+?&stateful=true")
.routeId("quartztimer")
.setHeader("ROUTING_KEY", simple("'trigger1'"))
.log(LoggingLevel.INFO, "Yeah quartz rocks, routingKey: ${header.ROUTING_KEY}");
}
}
org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/cntmx?characterEncoding=utf8
org.quartz.dataSource.myDS.user = blah
org.quartz.dataSource.myDS.password = hlab
org.quartz.dataSource.myDS.maxConnections = 12
我将这个应用程序复制到2个独立的项目中,并将它们命名为quartz-demo-1,quartz-demo-2。
然后我在同一个Apache服务器上运行这两个应用程序。
两个调度程序每2秒同时触发一次:
2015-09-14 14:23:28 quartz-demo-2 [MyClusteredScheduler-camel-1-1_Worker-3] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
2015-09-14 14:23:28 quartz-demo-1 [MyClusteredScheduler-camel-1_Worker-3] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
2015-09-14 14:23:30 quartz-demo-1 [MyClusteredScheduler-camel-1_Worker-4] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
2015-09-14 14:23:30 quartz-demo-2 [MyClusteredScheduler-camel-1-1_Worker-4] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
2015-09-14 14:23:32 quartz-demo-1 [MyClusteredScheduler-camel-1_Worker-5] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
2015-09-14 14:23:32 quartz-demo-2 [MyClusteredScheduler-camel-1-1_Worker-5] INFO quartztimer - Yeah quartz rocks, routingKey: 'trigger1'
理想的行为是,每两秒钟应该只有一个应用程序触发来模拟故障转移。如何配置此类行为?似乎两个调度程序都没有相互了解,即使它们从相同的石英表中读取。
非常感谢您的帮助。
答案 0 :(得分:1)
解决此问题的两种方法:
1)在QuartzComponent上定义propertiesFile属性。请参阅http://camel.apache.org/quartz2.html
上的配置quartz.properties文件- 或 -
2)在不同的JVM上运行第二个路由。以下是解决问题的原因:
这与与camel上下文关联的JMX管理名称有关。看起来Quartz2组件将管理名称(http://camel.apache.org/maven/camel-2.15.0/camel-core/apidocs/org/apache/camel/CamelContext.html#getManagementName())附加到org.quartz.scheduler.instanceName属性中定义的名称,如果您还没有定义如上所述的propertiesFile属性。
由于您在同一个JVM上运行,因此两个camel上下文将被分配唯一的管理名称,从而产生唯一的调度程序名称。这样可以防止群集按预期工作。