从deadletter队列到故障端点的Redeliver消息

时间:2012-10-29 10:32:46

标签: jms activemq message-queue apache-camel

我有一个Camel路线,例如:

<route errorHandlerRef="myDeadLetterErrorHandler">
    <from uri="activemq:queue:source"/>
    <to uri="activemq:queue:destA">
    <to uri="activemq:queue:destB">
    <to uri="activemq:queue:destC">
</route>

当一个端点发生故障时,我设置了一个redeliveryPolicy来重试发送消息一次,如果它总是失败,则将消息重新传递给DeadLetter队列。

现在我正在寻找一种方法将消息从deadletter队列发送到失败端点..有人有任何建议吗?

我正在考虑构建一个处理器来提取故障端点的信息,如下所示:

String lastEndpointUri = exchange.getProperty(Exchange.TO_ENDPOINT, String.class);

然后构建某种动态路由......是不是有更简单的解决方案?

3 个答案:

答案 0 :(得分:0)

如果你相信你可以简单地重新发送消息,它将在以后工作,然后增加重新传递计数。

否则,您可能需要一个更复杂的解决方案,因为您可能会对消息进行一些更改以实现它。也就是说,回答“为什么失败”的问题。在许多情况下,您需要人们查看消息/错误以确定是否可以执行某些操作。您需要什么逻辑非常依赖于您实施的内容。

对于瞬态错误(网络故障,数据库故障,磁盘已满等等)。,只需按照您的说法重新发送,对于应用程序错误,您需要三思而后行。

答案 1 :(得分:0)

另一种选择是仅处理Camel中的错误,而不是依赖于DLQ重定向逻辑。这使您可以更好地控制特定的错误情况,并可以根据需要对它们进行分类/重试。

类似的内容......有关详细信息,请参阅polling consumer

//main route to process message from a queue (needs to be fast)
from("activemq:queue:mainQ").process(...);

//handle any errors by simply moving them to an error queue (for retry later)
onException(Exception.class)
    .handled(true).to("activemq:queue:mainErrorQ");

//retry the error queue
from("timer://retryTimer?fixedRate=true&period=60000")
    .bean(myBean, "retryErrors"); 

...

public void retryErrors() {
    // loop to empty queue
    while (true) {
        // receive the message from the queue, wait at most 3 sec
        Exchange msg = consumer.receive("activemq:queue.mainErrorQ", 3000);
        if (msg == null) {
            // no more messages in queue
            break;
        }

        // send it to the starting queue
        producer.send("activemq:queue.mainQ", msg);
    }
}   

答案 2 :(得分:0)

感谢大家的回答,我很快解决了将端点放在单独的路由中并为每个人设置相同的redeliveryPolicy的问题。

    <route>
        <from uri="activemq:queue:source"/>
        <to uri="activemq:queue:destA1">
        <to uri="activemq:queue:destB1">
        <to uri="activemq:queue:destC1">
    </route>

<route errorHandlerRef="myDeadLetterErrorHandler">
    <from uri="activemq:queue:destA1"/>
    <to uri="activemq:queue:destA">
</route>

<route errorHandlerRef="myDeadLetterErrorHandler">
    <from uri="activemq:queue:destB1"/>
    <to uri="activemq:queue:destB">
</route>

...

通过这种方式,如果一个失败,消息将始终传递到每个端点,当失败端点返回时,消息将被重新传递。

我认为boday提出的解决方案是正确的,可能我将来会尝试这个解决方案。 我还发现,如果总消息顺序不重要,我们也可以使用“Broker Redelivery”使用特殊队列重新传递每条消息。 http://activemq.apache.org/message-redelivery-and-dlq-handling.html