当前位置: 首页 > 知识库问答 >
问题:

Resilience4J重试的预期行为是什么?

佴涵蓄
2023-03-14

我在Spring Boot项目中使用Resilience4J调用REST客户机,如下所示:

@Retry(name = "customerService")
public Customer getCustomer(String customerNumber) {
    restTemplate.exchange("https://customer-service.net", HttpMethod.GET, ..., customerNumber);
}
resilience4j.retry:
    instances:
        customerService:
            maxAttempts: 3
            waitDuration: 10s
            retryExceptions:
                - org.springframework.web.client.HttpServerErrorException

看到示例中包含了一个回退方法,我决定添加它,尽管我并不真的想调用不同的方法,我只想再次调用我的原始方法。

不管怎样,我指定了一个回落:

@Retry(name = "customerService", fallback = "customerFb")
public Customer getCustomer(String customerNumber) {
    return getCustomer();
}

private Customer customerFb(String customerNumber, HttpServerErrorException ex) {
    log.error("Could not retrieve customer... retrying...");
    return getCustomer();
}

private Customer getCustomer(String customerNumber) {
    return restTemplate.exchange("https://customer-service.net", HttpMethod.GET, ..., customerNumber);
}

现在,我看到回退方法被重试,但是每次都会抛出HttpServerErrorException,这意味着使用者将收到一个异常作为对其调用的响应。

谢谢

共有1个答案

姬墨竹
2023-03-14

问:为了使重试功能发挥作用,是否需要实现回退方法?

答:不,回退在Resilience4J重试功能中是可选的。

Resilience4j重试的行为:

当在@retry注释方法下发生预期的异常时,它不会记录有关异常的任何信息,但它会根据配置的maxattemps属性重试相同的方法。MaxAttemptions属性的默认值为3。在maxAttempts中,它抛出异常,可以在日志中看到。

还有诸如WaitDurationIntervalFunctionIgnoreExceptions..E.tc可以显式配置。有关更多信息,请参见文档链接。

要查看在用@retry注释的方法中的异常事件期间发生的实际情况,请允许RetryRegistry事件使用者打印接收到的事件。

package com.resilience.retry.config;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import io.github.resilience4j.retry.RetryRegistry;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class RetryRegistryEventListener {

    @Autowired
    private RetryRegistry registry;


    @PostConstruct
    public void postConstruct() {
        //registry.retry(<resilience retry instance name>)
        registry.retry("sample-api").getEventPublisher()
                .onRetry(ev -> log.info("#### RetryRegistryEventListener message: {}", ev));
    }
}
2021-11-01 14:55:12.337  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : Sample Api call receieved
2021-11-01 14:55:12.345  INFO 18176 --- [nio-8080-exec-1] c.r.r.config.RetryRegistryEventListener  : #### RetryRegistryEventListener message: 2021-11-01T14:55:12.344325600+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '1'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:12.350  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : messsage: 2021-11-01T14:55:12.344325600+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '1'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:22.359  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : Sample Api call receieved
2021-11-01 14:55:22.360  INFO 18176 --- [nio-8080-exec-1] c.r.r.config.RetryRegistryEventListener  : #### RetryRegistryEventListener message: 2021-11-01T14:55:22.360672900+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '2'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:22.361  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : messsage: 2021-11-01T14:55:22.360672900+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '2'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.

@Ferdturgusen:我相信你的代码有一些错误,否则它会正常工作。根据问题中给出的信息,我无法确切地找到问题所在。因此,我用resilience4j示例创建了一个样例spring boot,复制了您的问题,它对我来说很好,因此上传到Github供您参考。我建议您添加RetryRegistryEventListener类,并在事件日志中查找问题,如果仍未解决,请共享事件侦听器日志。

Github参考:使用resilience4j重试项目的示例spring-boot

 类似资料:
  • 问题内容: 我们正在重用一个使用spring java- config(使用@Configuration)定义其bean的项目,并且在一个此类中有一个init方法。 这里的预期行为是什么?何时调用此方法?关于豆子,那就是。即,此方法的行为是否完全像配置类是Bean一样(实际上是一个吗?) 我们观察到的是,根据操作系统的不同,可以在初始化进入配置类的Bean之前调用它,从而最终导致不完全依赖项的工作

  • 在流处理过程中遇到运行时异常时,流处理是否应该中止?它应该先结束吗?是否应在?异常是按原样重新生成还是已包装?的JavaDoc和java包。util。小溪对此无话可说。 我发现有关Stackoverflow的所有问题似乎都集中在如何从函数接口中包装一个已检查的异常,以使其代码能够编译。事实上,互联网上的博客帖子和类似文章都关注相同的警告。这与我无关。 根据我自己的经验,一旦抛出,序列流的处理就会中

  • 问题内容: 我注意到了一些意外的行为(相对于我的个人期望而言是意外的),我想知道是否是JVM中存在错误,或者这可能是一种边缘情况,在这种情况下我不了解某些确切的细节应该发生。假设我们自己在main方法中具有以下代码: 天真的期望是这样会印刷,最大的甚至可以代表。但是,我认为整数算术应该在Java中“翻转”,因此将1加到会导致。由于仍小于,因此循环将循环遍历负数甚至整数。最终它将回到0,并且此过程应

  • 差不多吧。是否有一个属性,一些配置,一些设置,可以帮助做到这一点很容易请?不用添加太多锅炉代码。 谢谢。

  • 但缺少透明装饰的美感。

  • 我的问题很简单,我知道我遗漏了一些非常明显的东西,我就是不知道它是什么。。。。 我对霍尔特·温特斯的测试预测结果是南,我不知道为什么。有人能帮忙吗? 我正在使用Jupyter笔记本电脑,并试图使用霍尔特-温特斯方法预测一个SKU的销售额。我甚至用了 以下是我使用的代码: 有人能指出我可能遗漏了什么吗?这似乎是一个简单的问题和一个简单的解决方案,但它踢我的屁股。 谢谢