我使用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&consumer.delay=10000&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。
还有其他人这样做吗?有什么理由不去?
答案 0 :(得分:1)
是的,确实如此。但是,您需要使用可扩展存储来保存已处理的消息集。您可以使用Hazelcast - http://camel.apache.org/hazelcast-idempotent-repository-tutorial.html或Infinispan - http://java.dzone.com/articles/clustered-idempotent-consumer - 具体取决于您的堆栈中已有的解决方案。当然,JDBC存储库可以工作,但前提是它符合所选的性能标准。