Próbuję użyć biblioteki sprężynowej Chmury 4 biblioteki, aby zaimplementować wyłącznik obwodu, gdy API API dostawcy zwraca 500 błędów lub gdy czas wywołuje, API nazywa się przy użyciu asynchttpclient. Problem wydaje się, że wyłącznik nigdy nie jest otwarty, a metoda awarii nigdy nie jest wykonywana, gdy API zwraca 500 błędów.

Czy może to być spowodowane faktem, że nadpisuję OnFailure (zrób to, aby uchwycić metryki)

Fabryka jest zadeklarowana w następujący sposób:

@Autowired
private CircuitBreakerFactory circuitBreakerFactory;

Konfiguracja fabryczna jest zdefiniowana w następujący sposób:

@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 nazywany jest następującą metodą, która ma również metodę wyłącznika i .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());

}

I wreszcie tutaj jest metodą awarki, którą chciałbym powołać:

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";
}
1
user130316 20 październik 2020, 18:12

1 odpowiedź

Najlepsza odpowiedź

Używasz asynchttpclient?

Możesz dać nasze Resililies4J Spring Boot 2 starter spróbuj. Zapewnia obsługę adnotacji, konfiguracji zewnętrznej, metryki, ponów próbę i wiele innych funkcji.

Jeśli mógłbyś zwrócić CompletableFuture, może to wyglądać następująco:

@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(..)
}
1
Robert Winkler 23 październik 2020, 08:21