camel-quartz2:集群配置

时间:2015-09-14 07:42:04

标签: java apache-camel quartz-scheduler load-balancing

我想设置带有聚类选项的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' 

理想的行为是,每两秒钟应该只有一个应用程序触发来模拟故障转移。如何配置此类行为?似乎两个调度程序都没有相互了解,即使它们从相同的石英表中读取。

非常感谢您的帮助。

1 个答案:

答案 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属性。

见第140行: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.camel/camel-quartz2/2.12.0/org/apache/camel/component/quartz2/QuartzComponent.java

由于您在同一个JVM上运行,因此两个camel上下文将被分配唯一的管理名称,从而产生唯一的调度程序名称。这样可以防止群集按预期工作。