Apache camel 骆驼幂等消费程序removeOnFailure的错误行为=true

Apache camel 骆驼幂等消费程序removeOnFailure的错误行为=true,apache-camel,idempotent,Apache Camel,Idempotent,我想知道以下是否是骆驼幂等消费者的预期行为: 对于路由,我有removeOnFailure=true,这意味着基本上当交换失败时,幂等消费者应该从存储库中删除标识符。这带来了一个非常有趣的场景,允许在exchange上进行复制 假设identifier=12345,并且第一次执行交换的尝试成功,这意味着identifier被添加到幂等存储库中。下一次尝试使用相同标识符(即12345)失败,因为它被捕获为重复消息(CamelDuplicateMessage)。但此时,如果removeOnFailu

我想知道以下是否是骆驼幂等消费者的预期行为:

对于路由,我有removeOnFailure=true,这意味着基本上当交换失败时,幂等消费者应该从存储库中删除标识符。这带来了一个非常有趣的场景,允许在exchange上进行复制

假设identifier=12345,并且第一次执行交换的尝试成功,这意味着identifier被添加到幂等存储库中。下一次尝试使用相同标识符(即12345)失败,因为它被捕获为重复消息(CamelDuplicateMessage)。但此时,如果removeOnFailure=true,则将从存储库中删除标识符,下次尝试时,该标识符将允许exchange成功通过,而不会捕获默认消息。因此,在exchange上创建一个复制空间

有人能告诉我这是预期的行为还是一些错误吗

示例路线:

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!"));

你的基本前提是错误的

下一次尝试使用相同的标识符(即12345)失败,因为捕获到该标识符 作为重复消息(复制消息)

如果存在重复的消息,则不会将其视为失败。它只是在进一步处理时被忽略(除非您将
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