在这里使用Apache 2.11.0。我正在编写一个基于Camel的小应用程序(使用Spring XML),它消耗队列中的消息(inputQueue
),聚合它们,处理聚合批处理,然后发出生成的报告。我想将这个应用程序(widget-reporter.war
)部署到多个Tomcat实例并对它们进行集群,这样如果一个节点出现故障,它仍然在其他节点上运行,报告仍然会生成。
到目前为止,路由的伪代码如下:
<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring">
<route id="myRoute">
<from uri="activemq:queue:inputQueue" />
<aggregate strategyRef="myStrategy" completionSize="500">
<correlationExpression>
<xpath>/fizz/buzz</xpath>
</correlationExpression>
<to uri="bean:reportGenerator?method=runReport"/>
</aggregate>
</route>
</camelContext>
因此,正如您所看到的,我们将消息从inputQueue
出列,将它们发送到聚合器(将它们与xpath表达式相关联),在我们达到500条消息后,我们将聚合的交换发送到reportGenerator
。
我完全在本地工作(1个节点)。现在我正在尝试将此应用程序部署到多个Tomcat实例,但我只希望它一次在1个节点上运行。换句话说,如果我将此应用程序部署到5个Tomcat实例,我不希望5个Tomcats同时从inputQueue
消耗:只有1个应该在任何给定时间运行,而另外4个应该在闲着,等待主要故障转移给他们。
看起来Camel Quartz
允许进行此类群集,但问题是它需要我使用quartz://
端点开始我的路由,而不是activemq
。所以我必须有这样的东西(这不起作用):
<route id="myRoute">
<from uri="quartz://runWidgetReporterExclusively?cron=0+15,45+0-16+?+*+SAT" />
<!-- Can't have 2 consecutive "from" endpoints... -->
<from uri="activemq:queue:inputQueue" />
<aggregate strategyRef="myStrategy" completionSize="500">
<correlationExpression>
<xpath>/fizz/buzz</xpath>
</correlationExpression>
<to uri="bean:reportGenerator?method=runReport"/>
</aggregate>
</route>
有人知道我怎么做:
答案 0 :(得分:2)
为此启用camel-zookeeper启用的RoutePolicy ...
ZooKeeper允许开箱即用的非常简单有效的领导者选举;此组件利用RoutePolicy中的此选举功能来控制何时以及如何启用路由。此策略通常用于故障转移方案,以控制跨基于Camel的服务器群集的路由的相同实例。一个非常常见的场景是一个简单的“主从”设置,其中有一个分布在一个集群中的路由的多个实例,但是其中只有一个,即主服务器的实例,应该一次运行。如果主站发生故障,则应从可用的从站中选择一个新的主站,并且应该启动该新主站中的路由。
答案 1 :(得分:0)
我自己从未这样做过,但是......
如果您放弃了对被动回退节点的要求(它们似乎对我来说似乎浪费了资源),您可以使用camel load balancer和sticky平衡策略。策略期望表达式关联属于特定“会话”的消息。您应该能够在路线中的聚合器中重复使用xpath expression。
您的示例路由并未表明您需要在Tomcat中运行Camel的原因。如果您的Camel应用程序不直接使用由Tomcat管理的资源,我建议您独立运行Camel应用程序;或者将其与Web应用程序分离以实现它。 Camel完全独立运行,使用org.apache.camel.spring.Main
类来启动你的弹簧和骆驼环境。