骆驼重试控制,有多个例外 [英] Camel retry control with multiple exceptions

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

问题描述

前言:我对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?

例如-我有两个异常 FooException BarException 。在我的路由中(或实际上在整个上下文中),我想重试FooExceptions 10次,但是 BarException s应该只重试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,当我将策略重置为仅尝试两次时,它(从逻辑上)得出结论:路由不应重试,并抛出异常。但是,在我的应用程序中,无论抛出多少 FooExceptions ,都应重试两次 BarExceptions 。同样,如果它交替抛出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个FooException和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天全站免登陆