3

我使用部署在 ActiveMQ 服务中的 Apache Camel 模块。

鉴于我使用 Spring DSL,并且文件routeContext中有路由定义(实现为)FilteringRouteContext.xml(简化):

<routeContext id="filteringRouteContext" xmlns="http://camel.apache.org/schema/spring">
    <route id="myFilteringRoute">
        <from uri="direct:filteringRoute"/>
        <idempotentConsumer messageIdRepositoryRef="idempotentRepository" skipDuplicate="false">
            <simple>${header.JMSType}</simple>
            <filter>
                <property>CamelDuplicateMessage</property>
                <stop/>
            </filter>
        </idempotentConsumer>
    </route>
</routeContext>

接下来,我在其他 XML 文件(简化)中配置了 Camel Context:

<import resource="classpath:FilteringRouteContext.xml"/>

    <camelContext xmlns="http://camel.apache.org/schema/spring">

        <routeContextRef ref="filteringRouteContext"/>

        <route id="myRoute1">
            <from uri="activemq:topic:source1" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target1" />
        </route>

        <route id="myRoute2">
            <from uri="activemq:topic:source2" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target2" />
        </route>

        <route id="myRoute3">
            <from uri="activemq:topic:source3" />
            <to uri="direct:filteringRoute" />
            <to uri="activemq:topic:target3" />
        </route>

    </camelContext>

    <bean id="idempotentRepository"
          class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository">
        <property name="cacheSize" value="10"/>
    </bean>

我希望共享路由(带有 id= myFilteringRoute)从filteringRouteContext声明为,使用 IoC 术语,每个依赖实例,因此来自单个 Camel 上下文(带有 id= myRoute1myRoute2myRoute3)的每条路由都应该使用它自己的共享路由实例(带有 id = myFilteringRoute),具有单独的内部状态、bean 实例等。

换句话说,来自 Camel Context 的每条路由(带有 id= myRoute1, myRoute2, myRoute3不应该使用相同的共享路由实例(带有 id= myFilteringRoute),而应该有自己完全独立的实例(具有完全分离的内部状态和 bean 实例)

请考虑我的共享路由(带有 id= myFilteringRoute)可能会使用更多的 bean,它们可能有不同的范围(singleton,prototyperequest)。

我的问题是:我可以使用单个 Camel 上下文来实现这个目标,还是需要将我的路线(使用 id= myRoute1, myRoute2, myRoute3)放在单独的 Camel 上下文中?我的问题的最佳解决方案是什么?

如果我使用多个 Camel 上下文,并且每个上下文都使用 bean 与 ActiveMQ ( org.apache.activemq.camel.component.ActiveMQComponent) 或其他消耗内部或系统资源的 bean 通信,是否会对性能产生重要影响?

或者使用 Java DSL 而不是 Spring DSL 来解决我的问题可能更好?

谢谢你。

4

2 回答 2

1

答案是 Camel 没有提供自动机制来做你想做的事。您示例中的所有路由都将共享同一个 idempotentRepository 实例。唯一的解决方案是提供一定程度的间接性。

例如,扩展 AbstractJdbcMessageIdRepository 以提供您自己的实现。然后,这可以在查找中包含 routeid 以确定消息是否已被处理。

或者,您可以拥有一组存储库,并根据路由 ID 从主 idempotentRepository 中查找要使用的存储库。

无论您做什么,您都需要编写使用最外层路由的路由 ID 来区分消息的代码。

于 2014-07-09T10:51:49.310 回答
1

当前的 Camel Spring DSL 定义是由 JAXB 在解组 xml 时创建的。此定义帮助骆驼运行时构建处理器并组装它们以路由消息。这样 routeContextRef 与您提到的范围无关。

但是对于您使用 Spring 使用 bean 元素创建的 bean,您可以根据需要定义范围,如果 Camel Spring DSL 中有 bean 引用,camel 只需从 Spring Application Context 中获取它。

为了回答您的问题, routeContextRef 只是提供了一种在骆驼上下文中共享路由定义实例的方法,如果您不想共享它们的实例,则需要在不同的 Spring 应用程序上下文中创建骆驼上下文,该上下文可以保存不同的 routeContext 实例.

于 2014-06-19T02:19:49.640 回答