- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 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
我的预期是,如果 restTemplate.exchange()
被调用并且客户服务响应 HttpServerErrorException
,getCustomer()
方法将等待 10 秒后再调用 3 次。
然而,事实并非如此。
此方法不再被调用,并立即抛出异常。
看到示例中包含回退方法,我决定添加它,即使我真的不想调用不同的方法,我只想再次调用我的原始方法。
无论如何,我指定了一个回退:
@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,这意味着消费者将收到异常作为对其调用的响应。
我的问题是:
是否需要实现回退方法才能使重试功能起作用?
和
抛出异常是预期的行为吗?难道我做错了什么?在所有重试尝试完成之前,我不希望此服务的调用方收到异常。
谢谢
最佳答案
问:是否需要实现回退方法才能使重试功能发挥作用?
回答:不,Fallback 在 Resilience4J 重试功能中是可选。
Resilience4J Retry
的
行为 :
启动时,resilience retry 会从 application.properties/yml 加载配置,否则将使用默认值进行初始化,如前所述 here in the documentation .
当调用带有@Retry 注释的方法时,它将处于重试监控之下。
如果属性resilience4j.retry.instances.<instance name>.retryExceptions
被显式配置,那么只有配置的异常才会被视为失败,并且只有这些失败才会触发重试,对于其余的异常,它在没有重试功能的情况下表现正常。
在 @retry
下发生预期异常时注释的方法,那么它不会记录任何关于异常的信息,但它会根据 maxAttempts
重试相同的方法。配置的属性。默认值 maxAttempts
属性是 3
.在 maxAttempts 之后它抛出异常并且可以在日志中看到。
还有类似 waitDuration
的属性, intervalFunction
, ignoreExceptions
.. e.tc 可以显式配置。如需更多信息,请查看文档链接。
在用 @retry
注释的方法中实际查看异常事件期间发生了什么, 使 RetryRegistry 事件消费者能够打印接收到的事件。
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));
}
}
example log:
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 引用:sample spring-boot with resilience4j retry project
关于java - Resilience4J Retry 的预期行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69792829/
我在 NodeJS 中的多台计算机上的服务器端服务中使用 Resilient。 弹性客户端调用的 API 之一受到速率限制。受到速率限制的请求会在响应中收到特定的 header /值,因此很容易判断何
我是一名优秀的程序员,十分优秀!