Все еще пытаюсь повторить попытку вручную, может также попробовать Spring Retry (2)

Spring Boot Java Spring
Все еще пытаюсь повторить попытку вручную, может также попробовать Spring Retry (2)

🤞 Персональная домашняя страница:@青城Sequencer Stone
🤞 Преимущества вентилятора:Добавить фан-базуОтвечайте на вопросы один на один, получайте бесплатные шаблоны резюме, улучшайте учебные материалы и т. д. и станьте королем новой эры!

Сразу после предыдущей статьи "Все еще повторяю попытку вручную, попробуйте Spring Retry (1)", щелкните Перейти.

В-четвертых, RetryTemplate

RetryTemplateявляется альтернативой использованию формы аннотации для повторной попытки.

4.1 RetryOperations

использоватьRetryOperationsинтерфейсSpring retry providesRetryOperationsСтратегия.

public interface RetryOperations {
​
 <T> T execute(RetryCallback < T > retryCallback) throws Exception;
 // other execute methods
​
 <T> T execute(RetryCallback < T > retryCallback, RecoveryCallback < T > recoveryCallback,
  RetryState retryState) throws Exception;
}

RetryCallbackПозволяет вставлять бизнес-логику, которую необходимо повторить в случае сбоя.

public interface RetryCallback <T> {
T doWithRetry(RetryContext context) throws Throwable;
}

4.2 RetryTemplate

RetryTemplateпри условииRetryOperationsконкретное воплощение. Создание bean-компонентов считается хорошей практикой.

    @Bean
    @ConditionalOnMissingBean
    public RetryTemplate retryTemplate(){
        final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
        simpleRetryPolicy.setMaxAttempts(4);
​
        final FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(1000L);
​
        return RetryTemplate.builder()
            .customPolicy(simpleRetryPolicy)
            .customBackoff(fixedBackOffPolicy)
            .retryOn(CustomRetryException.class)
            .build();
    }

Делайте модульные тесты.

    
    @Autowired
    pivate RetryTemplate retryTemplate;
​
    @Test
    void retryWithoutAnnotation(){
        try {
            String message = retryTemplate.execute(x ->                  retryService.retryWithoutAnnotation());
            log.info("message = "+message);
        } catch (CustomRetryException e) {
            log.error("Error while executing test {}",e.getMessage());
        }
    }

Как показано на следующем рисунке, он также повторил попытку четыре раза, но неrecoverстратегия.

fc44465528aeaf661622a9712a2aa3e.png

4.2 RecoveryCallback

execute, вы можете ввестиRecoveryCallbackОбратный вызов, после подтверждения того, что повторная попытка завершена, все равно возникает исключениеrecoveryповедение. Сигнатура метода выглядит следующим образом.

    public final <T, E extends Throwable> T execute(RetryCallback<T, E> retryCallback, RecoveryCallback<T> recoveryCallback) throws E {
        return this.doExecute(retryCallback, recoveryCallback, (RetryState)null);
    }

Итак, настраиваемRecoveryCallback.

@Slf4j
public class CustomRecoveryCallback implements RecoveryCallback<String> {
​
    @Override
    public String recover(RetryContext retryContext) throws Exception {
        log.info("Default Retry service test,total retry {}",retryContext.getRetryCount());
        return "Error Class :: " + retryContext.getLastThrowable().getClass().getName();
    }
}

Затем выполните модульные тесты.

    @Autowired
    private CustomRecoveryCallback customRecoveryCallback;
​
    @Test
    void retryWithoutAnnotation(){
        try {
            String message = retryTemplate.execute(x -> retryService.retryWithoutAnnotation(), customRecoveryCallback);
            log.info("message = "+message);
        } catch (CustomRetryException e) {
            log.error("Error while executing test {}",e.getMessage());
        }
    }

Как показано на следующем рисунке, после завершения повторной попытки наш пользовательскийrecover.

d5bfb79bc99998c1ba6ac3679df6c92.png

Пять, RetryListenerSupport

Что, если мы хотим настроить некоторые механизмы мониторинга и обработки событий в соответствии с различными этапами жизненного цикла повторных попыток? установить пользовательскийRetryListenerSupportможет помочь нам. мы наследуемRetryListenerSupport, и повторноOverride close,onError,openметод, три метода представляют

  • когда все попытки заканчиваются
  • Каждый раз, когда возникает исключение
  • Повторите попытку до официального старта.
@Slf4j
public class DefaultListenerSupport extends RetryListenerSupport {
​
    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        log.info("DefaultListenerSupport close");
        super.close(context, callback, throwable);
    }
​
    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        log.info("DefaultListenerSupport onError");
        super.onError(context, callback, throwable);
    }
​
    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        log.info("DefaultListenerSupport open");
        return super.open(context, callback);
    }
}

и строительствоRetryTemaplateУстановить времяwithListenerполе.

@Bean
@ConditionalOnMissingBean
public RetryListenerSupport retryListenerSupport(){
    return new DefaultListenerSupport();
}
​
@Bean
@ConditionalOnMissingBean
public RetryTemplate retryTemplate(RetryListenerSupport retryListenerSupport){
​
    ...
    
    return RetryTemplate.builder()
        .customPolicy(simpleRetryPolicy)
        .customBackoff(fixedBackOffPolicy)
        .withListener(retryListenerSupport)
        .retryOn(CustomRetryException.class)
        .build();
}

Запустите модульный тест, и результат будет следующим.

908cfaf861fd507821e7005ca3214e5.png

6. Резюме

В этой статье мы увиделиSpring retryразличные функции, мы знаем, что их использование делает приложение более надежным. мы практикуемсяSpring RetryНаиболее распространенные варианты использования включают@RetryableПримечания иRetryTemplate.

Итак, где мы можем использоватьSpring RetryШерстяная ткань? Есть два предложения

  • Используйте повторы только для временных ошибок. Не рекомендуется использовать его при постоянных ошибках, так как это может привести к проблемам с производительностью системы.
  • Это не замена фьюзам, по возможности лучше использовать и фьюзы, и повторители.

Мальчик, ты не можешь видеть достаточно? нажмите на каменьПодробное описание, Просто нажмите и посмотрите, может быть будут сюрпризы? Добро пожаловать в поддержкуНравится/Подписывайтесь/Комментируйте, ваша поддержка — моя самая большая мотивация для Gengwen, спасибо!