如何在Camel中实现超时重试?

时间:2014-11-10 06:36:11

标签: timeout apache-camel

我应该如何实现Camel路由以实现以下目标?

  1. 通过将请求发送到JMS代理来调用外部服务
  2. 等待其响应 在另一个帖子上 ,因此原始帖子未被阻止
  3. 如果请求超时,则从步骤2开始(此部分可以通过轮询完成) ;否则继续
  4. 处理回复
  5. 我的测试路线实施

    // Simulate receiving message from upstream
    from("direct:jmsStart")
            .setExchangePattern(ExchangePattern.InOnly)
            .validate(new TestValidator("Some basic validation"))
            .to("seda:sell");
    
    // Sell Flow Starts
    from("seda:sell")
            .transform(new TestTransformer("Convert to internal data structure"))
            .validate(new TestValidator("ValidateSellStatus"))
            .process(new TestProcessor("Prepare request to external system"))
            .process(new TestProcessor("Persist the request to DB")) // <== Any better persistence suggestion??
            .to("seda:jmsRequestToExternal");
    
    // Simulate External System Processing
    from("seda:jmsRequestToExternal")
            .log(LoggingLevel.INFO, LOGGER, "External System Processing...")
            .delay(1000).to("seda:jmsReplyFromExternal");
    
    // External System response received
    from("seda:jmsReplyFromExternal")
            .process(new TestProcessor("Mark Complete"))
            .log(LoggingLevel.INFO, LOGGER, "Send reply to upstream");
    
    // Trigger retry - resend those requests without a response
    from("timer://poller?period=30000")
            .process(new TestProcessor("Get pending requests from DB"))  // <== Any better persistence suggestion??
            .to("seda:jmsRequestToExternal");
    

    为了实现低延迟,所有路由/子路由不应相互阻塞。想了解是否有更好的实现可以达到同样的效果?据我了解,Camel上的重新传递机制似乎依赖于阻塞超时或异常机制,这可能不适合低延迟应用。

1 个答案:

答案 0 :(得分:8)

您需要使用带有重新传递策略的异常处理程序,也称为Camel中的RedeliveryErrorHandler。这个错误处理程序允许你设置重试次数,并设置像reties之间的延迟等。

以下属性适用于RedeliveryErrorHandler

  • MaximumRedeliveries:允许的最大重新传递尝试次数。 0用于禁用重新传递,-1将尝试永久重新传递,直到成功。

  • RedeliveryDelay:修复每次重新发送尝试之间的延迟(以毫秒为单位)。

  • MaximumRedeliveryDelay:重新传递延迟的上限(以毫秒为单位)。当您指定非固定延迟(例如指数退避)时使用此选项,以避免延迟增长过大。使用带有重新传递的错误处理程序

  • AsyncDelayedRedelivery:指示Camel是否应使用异步延迟重新传递。当计划在将来重新传递重新传递时,Camel通常必须阻止当前线程,直到重新传输为止。通过启用此选项,您可以让Camel使用调度程序,以便异步线程执行重新传递。这可确保在等待重新传递时不会阻塞任何线程。

  • BackOffMultiplier:用于乘以每个后续延迟的指数退避乘数..RedeliveryDelay是起始延迟。默认情况下禁用指数退避。

  • CollisionAvoidanceFactor:计算随机延迟偏移时使用的百分比(以避免在下次尝试时使用相同的延迟)。将以RedeliveryDelay作为起始延迟开始。默认情况下禁用闪避避免。

  • DelayPattern:用于计算延迟的模式。 Thepattern允许您为间隔组指定固定延迟。例如,模式&#34; 0:1000; 5:5000; 10:30000&#34;对于尝试0到4将使用1秒延迟,对于尝试5到9将使用5秒,对于后续尝试将使用30秒。

  • RetryAttemptedLogLevel:执行重新传递尝试时使用的日志级别。

  • RetriesExhaustedLogLevel:所有重新传递尝试失败时使用的日志级别。

  • LogStackTrace boolean true指定在所有重新传递尝试失败时是否应记录堆栈跟踪。

  • LogRetryStackTrace:指定在传递失败时是否应记录堆栈跟踪。

  • LogRetryAttempted:指定是否应记录重新传递尝试。

  • LogExhausted:指定是否用尽重新传递尝试(当所有重新传递时) 尝试失败了)应该记录下来。

  • LogHandled:指定是否应记录处理的异常。

在Java中使用它很简单,您可以使用以下代码:

errorHandler(defaultErrorHandler()
.maximumRedeliveries(3) 
.backOffMultiplier(4)
.retryAttemptedLogLevel(LoggingLevel.WARN));

或者如果您想要Spring XML DSL:

<errorHandler id="myErrorHandler" type="DefaultErrorHandler"
    <redeliveryPolicy maximumRedeliveries="5"
       retryAttemptedLogLevel="WARN"
       backOffMultiplier="2"
       useExponentialBackOff="true"/>
</errorHandler>

您可以使用它来重试Web服务调用一段时间,如果在5次重试尝试后无法连接,则抛出异常。