Camel 重试控制多异常 [英] Camel retry control with multiple exceptions

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

问题描述

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

使用 Camel 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
    {
    }
}

结果,您的意见获得批准:即使我们只有 4 个 FooExceptions 和 1 个 BarException,交付尝试在 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.

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

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