Apache Camel的幂等消费模式是否具有可扩展性?

时间:2014-06-03 08:00:40

标签: sql apache-camel idempotent enterprise-integration

我使用Apache Camel 2.13.1来轮询数据库表,其中包含超过300k行。我希望使用Idempotent Consumer EIP来过滤已经处理过的行。

我想知道,实施是否真的可扩展。我的骆驼背景是: -

<camelContext xmlns="http://camel.apache.org/schema/spring">
        <route id="main">
        <from
            uri="sql:select * from transactions?dataSource=myDataSource&amp;consumer.delay=10000&amp;consumer.useIterator=true" />
        <transacted ref="PROPAGATION_REQUIRED" />
        <enrich uri="direct:invokeIdempotentTransactions" />                
        <!-- Any processors here will be executed on all messages -->
    </route>

    <route id="idempotentTransactions">
        <from uri="direct:invokeIdempotentTransactions" />
        <idempotentConsumer
            messageIdRepositoryRef="jdbcIdempotentRepository">
            <ognl>#{request.body.ID}</ognl>
            <!-- Anything here will only be executed for non-duplicates -->
            <log message="non-duplicate" />
            <to uri="stream:out" />
        </idempotentConsumer>
    </route>            
</camelContext>

似乎每10秒(通过consumer.delay参数)处理完整的300k行,这似乎效率很低。我希望某种反馈循环作为模式的一部分,以便提供过滤器的查询可以利用已处理的行集。

但是,CAMEL_MESSAGEPROCESSED表中的messageid列具有

模式
 {1908988=null}

其中1908988是request.body.ID我已将EIP设置为key,因此这并不容易合并到我的查询中。

有没有更好的方法将CAMEL_MESSAGEPROCESSED表用作select语句的反馈循环,以便SQL服务器执行大部分负载?

更新

所以,我发现这是我的ognl代码导致奇数消息id列值。将其更改为

<el>${in.body.ID}</el>

修复了它。所以,既然我有一个可用的messageId列,我现在可以改变我的&#39;来自&#39; SQL查询到

select * from transactions tr where tr.ID IN (select cmp.messageid from CAMEL_MESSAGEPROCESSED cmp where cmp.processor = 'transactionProcessor')

但我仍然认为我正在破坏Idempotent Consumer EIP。

还有其他人这样做吗?有什么理由不去?

1 个答案:

答案 0 :(得分:1)

是的,确实如此。但是,您需要使用可扩展存储来保存已处理的消息集。您可以使用Hazelcast - http://camel.apache.org/hazelcast-idempotent-repository-tutorial.html或Infinispan - http://java.dzone.com/articles/clustered-idempotent-consumer - 具体取决于您的堆栈中已有的解决方案。当然,JDBC存储库可以工作,但前提是它符合所选的性能标准。