【问题标题】:Spring Cloud Resilience4j Circuitbreaker not calling fallbackSpring Cloud Resilience4j Circuitbreaker 未调用回退
【发布时间】:2021-02-03 10:55:59
【问题描述】:

我正在尝试使用 Spring Cloud Resilience4j 库来实现一个断路器,以便在供应商 api 返回 500 错误或超时时,使用 AsyncHttpClient 调用该 api。问题似乎是,当 API 返回 500 错误时,断路器永远不会打开,并且 fallback 方法永远不会执行。

可能是因为我覆盖了 onFailure(这样做是为了捕获指标)

工厂声明如下:

@Autowired
private CircuitBreakerFactory circuitBreakerFactory;

工厂配置定义如下:

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> specificCustomConfiguration1() {

    TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
            .timeoutDuration(Duration.ofSeconds(2))
            .build();
    CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
            .failureRateThreshold(50)
            .waitDurationInOpenState(Duration.ofMillis(1000))
            .slidingWindowSize(2)
            .build();

    return factory -> factory.configure(builder -> builder.circuitBreakerConfig(circuitBreakerConfig)
            .timeLimiterConfig(timeLimiterConfig).build(), "circuitBreaker");
}

API调用如下方法,也有断路器和.run方法:

private void getRecommendationsAsync(final GatewayRecommendationsRequest request,
                                     final String variantName,
                                     final ThinkCallbackHandler callbackHandler)
        throws URISyntaxException, JsonProcessingException {

    CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitBreaker");



    final AsyncHttpClient.BoundRequestBuilder builder = requestBuilder
            .prepareRequest(asyncHttpClient, request, variantName);


    circuitBreaker.run(() -> builder.execute(new AsyncCompletionHandler<Response>() {
        @Override
        public Response onCompleted(final Response response)
                throws Exception {
            processResponseStatus(response, variantName);

            GatewayRecommendations gatewayRecommendations = ((ThinkResponseMapper) responseMapper).map(request,
                    response,
                    useCaseId,
                    variantName);
            validator.validateResponse("/v1/recommendations", Request.Method.GET, response, gatewayRecommendations);
            callbackHandler.onSuccess(gatewayRecommendations);
            return response;
        }

        @Override
        public void onThrowable(final Throwable t) {
            callbackHandler.onFailure(t, recommendationsUri + " " + parameters.toString(), variantName);
        }


    }), throwable -> fallback());

}

最后是我想调用的后备方法:

public String fallback() {
    LOGGER.warn("The fallback method is being used");
    System.out.println("Fallback Method is being executed");
    return "The circuit breaker is open";
}

【问题讨论】:

    标签: spring spring-cloud asynchttpclient circuit-breaker resilience4j


    【解决方案1】:

    你在用AsyncHttpClient吗?

    您可以试试我们的Resilience4j Spring Boot 2 Starter。它提供注释支持、外部配置、指标、重试和更多功能。

    如果您可以返回 CompletableFuture,它可能如下所示:

    @CircuitBreaker(name = "circuitBreaker", fallbackMethod="fallback")
    public CompletableFuture<GatewayRecommendations> getRecommendationsAsync(final GatewayRecommendationsRequest request,
                                         final String variantName,
                                         final ThinkCallbackHandler callbackHandler)
            throws URISyntaxException, JsonProcessingException {
    
        final AsyncHttpClient.BoundRequestBuilder builder = requestBuilder
                .prepareRequest(asyncHttpClient, request, variantName);
    
        return builder.execute().toCompletableFuture()            
                .exceptionally(t -> { /* Something wrong happened... */  } )
                .thenApply(response -> { /*  Validate response and extract GatewayRecommendations  */  
       });
    
    
    }
    
    public CompletableFuture<GatewayRecommendations> fallback(RequestNotPermitted ex) {
        // The circuit breaker is open
        // Return a static list of recommendations
        return CompletableFuture.completedFuture(..)
    }
    

    【讨论】:

    • 您好罗伯特,感谢您回来。是的,我意识到返回类型和执行方法是问题所在。不,它是 com.ning.http.client.AsyncHttpClient 版本,不幸的是它没有可完成的未来方法。将看看这个,也许将服务重写为 Reactive 模型。谢谢赞恩
    • 如果回答还有帮助,请采纳;)
    • 当然。转向反应式将使用反应式 CB,谢谢罗伯特 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 2020-09-10
    • 2017-07-28
    • 2020-07-12
    • 2021-08-18
    • 2021-11-05
    相关资源
    最近更新 更多