我想知道以下是Camel幂等消费者的预期行为:
我对路由有removeOnFailure = true,这意味着当交换失败时,幂等消费者应该从存储库中删除标识符。这提出了一个非常有趣的场景,允许在交易所重复。
假设我有标识符= 12345并且首次尝试执行交换是Succesfull,这意味着标识符被添加到幂等存储库中。下次尝试使用相同的标识符,即12345失败,因为它被捕获为重复消息(CamelDuplicateMessage)。但此时,如果removeOnFailure = true,将从存储库中删除标识符,该标识符在下次尝试时将允许交换成功通过,而不会捕获默认消息。因此,在交易所创造一个重复的空间。
有人可以告知这是预期的行为还是一些错误?
示例路线:
from("direct:Route-DeDupeCheck").routeId("Route-DeDupeCheck")
.log(LoggingLevel.DEBUG, "~~~~~~~ Reached to Route-DeDupeCheck: ${property.xref}")
.idempotentConsumer(simple("${property.xref}"), MemoryIdempotentRepository.memoryIdempotentRepository()) //TODO: To replace with Redis DB for caching
.removeOnFailure(true)
.skipDuplicate(false)
.filter(exchangeProperty(Exchange.DUPLICATE_MESSAGE).isEqualTo(true))
.log("~~~~~~~ Duplicate Message Found!")
.to("amq:queue:{{jms.duplicateQueue}}?exchangePattern=InOnly") //TODO: To send this to Duplicate JMS Queue
.throwException(new AZBizException("409", "Duplicate Message!"));
答案 0 :(得分:1)
你的基本前提是错误的。
接下来尝试使用相同的标识符,即12345失败,因为它被捕获 作为重复消息(CamelDuplicateMessage)
如果有重复的消息,则不会将其视为失败。它只是被进一步处理忽略(除非你将skipDuplicate
选项设置为true)。
因此你所解释的场景不可能发生。
测试非常简单。考虑到你有这样的路线,
public void configure() throws Exception {
//getContext().setTracing(true); Use this to enable tracing
from("direct:abc")
.idempotentConsumer(header("myid"),
MemoryIdempotentRepository.memoryIdempotentRepository(200))
.removeOnFailure(true)
.log("Recieved id : ${header.myid}");
}
}
像这样的制片人
@EndpointInject(uri = "direct:abc")
ProducerTemplate producerTemplate;
for(int i=0, i<5,i++) {
producerTemplate.sendBodyAndHeader("somebody","myid", "1");
}
您在日志中看到的是
INFO 18768 --- [tp1402599109-31] route1 : Recieved id : 1
只有一次。