带多个异常的骆驼重试控制 [英] Camel retry control with multiple exceptions

查看:21
本文介绍了带多个异常的骆驼重试控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前言:我对 Camel 还很陌生,在尽可能地消化了 Camel 的实际操作之后,我正在将其调整到我正在进行的项目中.在这个项目中,我们有一些相当复杂的错误处理,我想确保我可以在我们对代码进行骆驼化时复制它.

Preface: I'm fairly new to Camel, and after digesting Camel in action as best as possible, I'm adapting it to a project I'm on. In this project, we have some rather complex error handling, and I want to make sure I can replicate this as we Camel-ize our code.

在我们的项目中(与大多数情况一样),有一组我们想要重试的异常和一组我们不想重试的异常 - 但更具体地说,有一组我们比其他项目更想重试(并非所有可恢复的错误可以同样处理).在这种情况下,我试图定义一个 onException 块来更改重新投递策略.但是,似乎 Exchange 维护计数 (Exchange.REDELIVERY_COUNTER),并且此计数不依赖于引发的异常.有没有办法让这个计数特定于给定的异常?

On our project (as most) there are a set of Exceptions we want to retry and a set that we don't - but more specifically, there are a set that we want to retry more than others (not all recoverable errors can be treated the same). In this case, I was attempting to define an onException block to change the redelivery policy. However, it seems that the Exchange maintains the count (Exchange.REDELIVERY_COUNTER) and that this count is not dependent on which exception is thrown. Is there a way to make this count be specific for a given exception?

例如 - 我有两个异常 FooExceptionBarException.在我的路线中(或实际上在整个上下文中),我想重试 FooExceptions 10 次,但 BarExceptions 应该只重试 2 次.所以上下文将包含:

For example - I have two exceptions FooException and BarException. In my route (or really in the whole context), I want to retry FooExceptions 10 times, but BarExceptions should only retry 2 times. So the context will contain:

<onException>
     <exception>my.exception.FooException</exception>
     <redeliveryPolicy maximumRedeliveries="10" redeliveryDelay="2000"
</onException>

<onException>
      <exception>my.exception.BarException</exception>
      <redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="5000"
</onException>

现在,问题是 - 如果我的应用程序抛出 FooException 并重试 4 次(每次抛出 FooException),然后在第 5 次尝试时,它会抛出 BarException,似乎这种工作方式是 Exchange 的 REDELIVERY_COUNTER 为 5,当我将策略重置为仅尝试两次时,它(逻辑上)得出结论不应重试路由并将异常抛出.但是,在我的应用程序中,应该重试两次 BarExceptions,而不管抛出了多少 FooExceptions.同样,如果它交替抛出 Foo 和 Bar 异常,我希望它只增加给定异常的计数器.

Now, the concern - if my application throws a FooException and retries 4 times (each time throwing a FooException) and then on the 5th attempt, it throws a BarException, it seems that the way this works is the Exchange will have a REDELIVERY_COUNTER of 5, and when I reset the policy to only try twice, it (logically) concludes that the route should not be retried and throws the exception back out. However, in my application BarExceptions should be retried twice, regardless of how many FooExceptions get thrown. And likewise, if it alternates throwing Foo and Bar exceptions, I would like it to only increment the counter for the given exception.

Camel in Action 的最后提倡使用 retryWhile - 这是获取我正在寻找的那种控制的唯一方法吗?我是否需要创建一个知道每个异常计数的有状态 bean?还是我忽略了一些简单的事情?我想确保当我接近这个重构时,我不会让我们走上一条丑陋的道路.

The very end of Camel in Action promotes using a retryWhile - is this the only way to grab the kind of control I'm looking for? Do I need to create a stateful bean that is aware of the count per exception? Or am I overlooking something simple? I want to make sure that as I approach this refactor I don't start us off on an ugly path.

使用骆驼 2.10.1

Using Camel 2.10.1

推荐答案

我通过以下测试检查了您的案例:

I checked your case with following test:

import org.apache.camel.EndpointInject;
import org.apache.camel.Exchange;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

import java.util.concurrent.atomic.AtomicLong;

/**
 * @author Illarion Kovalchuk
 *         Date: 12/7/12
 *         Time: 2:58 PM
 */
public class Test extends CamelTestSupport
{

    private static final String MIDDLE_QUEUE = "seda:middle";

    @EndpointInject(uri = "mock:result")
    protected MockEndpoint resultEndpoint;

    @Produce(uri = "direct:start")
    protected ProducerTemplate template;

    private Processor processor = new Processor();

    @Test
    public void shouldRedeliverOnErrors() throws Exception
    {
        resultEndpoint.expectedBodiesReceived("Body");
        template.sendBodyAndHeader(MIDDLE_QUEUE, "Body", "Header", "HV");
        resultEndpoint.assertIsNotSatisfied();
    }

    @Override
    protected RouteBuilder createRouteBuilder()
    {
        return new RouteBuilder()
        {
            @Override
            public void configure() throws Exception
            {

                onException(FooException.class)
                        .redeliveryDelay(2000)
                        .maximumRedeliveries(10);

                onException(BarException.class)
                        .redeliveryDelay(5000)
                        .maximumRedeliveries(2);

                from(MIDDLE_QUEUE)
                        .bean(Processor.class, "process")
                        .to(resultEndpoint)
                        .end();
            }
        };
    }

    public static class Processor
    {
        private static AtomicLong retryState = new AtomicLong(0L);

        public static void process(Exchange e) throws FooException, BarException
        {
            long rs = retryState.getAndAdd(1L);
            if (rs < 4)
            {
                System.err.println("Foo Attempt "+ rs);
                throw new FooException();
            }
            if (rs == 4)
            {
                System.err.println("Bar Attempt "+ rs);
                throw new BarException();
            }
            System.err.println("Normal Attempt "+ rs);
        }
    }

    public static class FooException extends Throwable
    {
    }

    private static class BarException extends Throwable
    {
    }
}

因此,您的同意被批准:在 BarException 之后交付尝试已用尽,即使我们只有 4 个 FooExceptions 和 1 个 BarException.

As the result, your concirn was approved: delivery attempts gets exhausted after BarException, even if we have only 4 FooExceptions and 1 BarException.

很遗憾,我现在不能完全回答你的问题,但我正在深入研究它,如果有新的东西会更新我的答案.

Unfortunately I can't answer your question fully right now, but I am digging into it and will updated my unswer if get something new.

这篇关于带多个异常的骆驼重试控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆