我想用Resilience4j来处理容错,我用的是断路器和定时器限制。
我想分离业务逻辑的容错行为,不要“弄脏”我的业务代码。
public class MyCommand {
private static final CircuitBreaker circuitBreaker;
private Long param1, param2;
private MyService myService;
private static final TimeLimiter timeLimiter;
static {
long ttl = 50000;
TimeLimiterConfig configTimerLimit
= TimeLimiterConfig.custom().timeoutDuration(Duration.ofMillis(ttl)).build();
timeLimiter = TimeLimiter.of(configTimerLimit);
// I got the configuration from a class that I created.
circuitBreaker = CircuitBreaker.of("my", CircuitBreakerConfigOptions.defaultForExternalService());
}
public MyCommand(Long param1, Long param2, MyService myService) {
this.param1 = param1;
this.param2 = param2;
this.myService = myService;
}
public String run() {
Callable<String> stringCallable = TimeLimiter.decorateFutureSupplier(timeLimiter,
() -> CompletableFuture.supplyAsync(() -> myService.hello(param1, param2)));
Callable<String> callable = CircuitBreaker.decorateCallable(circuitBreaker, stringCallable);
return Try.of(callable::call).recover(t -> fallback(t)).get();
}
protected String fallback(Throwable throwable) {
Callable<String> stringCallable = TimeLimiter.decorateFutureSupplier(timeLimiter,
() -> CompletableFuture.supplyAsync(() -> myService.otherHello(param1, param2)));
return Try.of(stringCallable::call).getOrElse("Fallback");
}
}
@ApiOperation(value = "Only to test")
@GetMapping(value = "/execute", produces = MediaType.APPLICATION_JSON)
public String execute() {
return new MyCommand(1L, 2L, new MyService()).run();
}
2-我如何有这个应用程序的许多实例,断路器为每个实例单独工作?我是对的?
我从你的问题中了解到的是--你需要一个弹性4J的断路器,它应该是精的,即不要扰乱你的业务逻辑。
所以我建议把断路器保护放在run()方法周围。下面的代码将详细说明-
你的控制器-
@ApiOperation(value = "Only to test")
@GetMapping(value = "/execute", produces = MediaType.APPLICATION_JSON)
public String execute() {
return new MyCommand().run();
}
public class MyCommand {
@CircuitBreaker(name = "RUN_METHOD_PROTECTION") // <---- here is our circuit breaker annotation code top of below your business code... and that’s it.
Your_Response run(Your_Request){
// Your business logic written here...
}
resilience4j.circuitbreaker:
backends:
RUN_METHOD_PROTECTION:
registerHealthIndicator: true
slidingWindowSize: 100 # start rate calc after 100 calls
minimumNumberOfCalls: 100 # minimum calls before the CircuitBreaker can calculate the error rate.
permittedNumberOfCallsInHalfOpenState: 10 # number of permitted calls when the CircuitBreaker is half open
waitDurationInOpenState: 10s # time that the CircuitBreaker should wait before transitioning from open to half-open
failureRateThreshold: 50 # failure rate threshold in percentage
slowCallRateThreshold: 100 # consider all transactions under interceptor for slow call rate
slowCallDurationThreshold: 2s # if a call is taking more than 2s then increase the error rate
recordExceptions: # increment error rate if following exception occurs
- org.springframework.web.client.HttpServerErrorException
- java.io.IOException
- org.springframework.web.client.ResourceAccessException
@Bean
public CircuitBreaker MyCircuitBreaker(){
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.slidingWindow(100,100, CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
.failureRateThreshold(50)
.build();
CircuitBreakerRegistry registry = CircuitBreakerRegistry.of(config);
CircuitBreaker circuitBreaker = registry.circuitBreaker("your_run_method_CircuitBreker"); // here you are registering your circuit breaker with a unique tag. And in future you refer this tag you get a same circuit breaker.
return circuitBreaker;
}
private CircuitBreaker circuitBreaker; // Assume you have injected the value from CircuitBreaker bean
@ApiOperation(value = "Only to test")
@GetMapping(value = "/execute", produces = MediaType.APPLICATION_JSON)
public String execute() {
Function<Your_Request, Your_Response> decorated = CircuitBreaker
.decorateFunction(circuitBreaker, new MyCommand().run());
return decorated.apply();
}
这样,您也从来没有干扰过您的业务逻辑。
断路器将处于闭合或半断开状态无限时间,直到达到最小的呼叫次数,对吗?有什么办法我可以设置什么时候没有调用在数量的时间,它将转为关闭状态?另外,在半开状态下,是否有可能使最小呼叫数大于允许的呼叫数?谢谢。
我有一个关于带Resilience4J(不仅仅是Resilience4J)的Spring Cloud断路器的快速问题。 这两个项目都非常棒。然而,目前,我们经常以撤退告终。这意味着,当第三方服务真的很好时,我们最终还是会选择后退。 这可能是我自己的问题,因此,我想问一个特定配置的问题。 我想告诉当前配置做以下操作:断路器。(我将使用好的,坏的,和一半好/一半坏的状态。 > 当状态是一半好/一半坏:
我正面临使用Spring Cloud Resilience 4j的断路器实现的问题。 在一些教程之后,我尝试在项目中添加必要的依赖项。此外,尝试添加配置,但电路仍然没有打开,并且没有调用回退方法。 对于用例,我正在从我的服务调用外部 API,如果该外部 API 关闭,那么在几次调用后,我需要启用断路器。 请从不同的文件中找到代码片段。 我是断路器模式的新手。我们将非常感谢您的帮助。 pom.xml
我可以看到,我可以使用以下代码以编程方式将状态设置为强制打开:CircuitBreaker强制打开状态 但是有没有一种方法可以设置一个属性,在应用程序启动时立即将状态设置为此,以便可以与测试一起使用呢?
根据入门指南(https://Resilience4j.readme.io/docs/get-started-3)和演示项目(https://github.com/Resilience4j/Resilience4j-spring-boot2-demo),我想自己测试它,创建一个更简单的测试应用程序。 代码如下:
我想将我的断路器配置从application.yml文件移到某个配置java文件作为bean声明信标,这使得application.yml文件变得很大,我是否可以从applciation.yml中删除配置并使用配置注释来定义断路器配置。我有配置java文件,代码如下: 在我的服务文件中,我正在注释断路器的方法,如 在目前的实现中,我的断路器无法达到开路状态。请给我一些建议