Как объединить Retryable и CircuitBreaker вместе весной?

Аннотация Spring @Retryable повторится три раза (по умолчанию) и вернется к методу @Recovery. @CircuitBreaker, однако, будет повторять попытку один раз и отступать при закрытии состояния.

Я хочу объединить эти два: когда состояние автоматического выключателя замкнуто, произойдет повторная попытка три раза, прежде чем откатится назад (для обработки переходных ошибок), если состояние разомкнуто, произойдет прямое восстановление.

Любой изящный способ сделать это? Возможный подход - реализовать логику повторных попыток внутри функции, но я чувствую, что это не будет лучшим решением.

1 ответ

@CircuitBreaker уже реализует @Retry как stateful = true, поэтому он знает, сколько вызовов не удалось.

Я думаю, что лучшим подходом здесь будет использование RetryTemplate внутри вашего метода:

@CircuitBreaker(maxAttempts = 2, openTimeout = 5000l, resetTimeout = 10000l)
void call() {
  retryTemplate.execute(new RetryCallback<Void, RuntimeException>() {
    @Override
    public Void doWithRetry(RetryContext context) {
      myService.templateRetryService();
    }
  });
}

Объявление RetryTemplate:

@Configuration
public class AppConfig {

  @Bean
  public RetryTemplate retryTemplate() {
      RetryTemplate retryTemplate = new RetryTemplate();

      FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
      fixedBackOffPolicy.setBackOffPeriod(2000l);
      retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

      SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
      retryPolicy.setMaxAttempts(2);
      retryTemplate.setRetryPolicy(retryPolicy);

      return retryTemplate;
  }
}

Включение Spring Retry в проекте:

@Configuration
@EnableRetry
public class AppConfig { ... }
Другие вопросы по тегам