Как настроить RestTemplate для повторных вызовов для определенного кода состояния ответа?

#java #spring-boot #spring-mvc #spring-cloud

#java #весенняя загрузка #spring-mvc #spring-облако

Вопрос:

У меня возникли проблемы с настройкой RestTemplate для повторных попыток удаленных вызовов. Кто-нибудь знает, как настроить RestTemplate для повторных вызовов после получения кода состояния ответа 503?

Комментарии:

1. Можете ли вы поделиться тем, что вы пробовали?

2. посмотрите здесь resilience4j.readme.io

Ответ №1:

Да, это возможно, вы можете попробовать пользовательскую политику повторных попыток.

 class InternalServerExceptionClassifierRetryPolicy extends ExceptionClassifierRetryPolicy {
public InternalServerExceptionClassifierRetryPolicy() {
    final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
    simpleRetryPolicy.setMaxAttempts(3);

    this.setExceptionClassifier(new Classifier<Throwable, RetryPolicy>() {
        @Override
        public RetryPolicy classify(Throwable classifiable) {
            if (classifiable instanceof HttpServerErrorException) {
                // For 503
                if (((HttpServerErrorException) classifiable).getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) {
                    return simpleRetryPolicy;
                }
                return new NeverRetryPolicy();
            }
            return new NeverRetryPolicy();
        }
    });
}}
  

Если просто вызвать его, как показано ниже:

 RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new InternalServerExceptionClassifierRetryPolicy())
  

Ответ №2:

Повторите попытку в блоке catch

 try {
    responseEntity = restTemplate.exchange(endpoint, HttpMethod.POST, entity, MyResponse.class);
} catch (HttpClientErrorException hcee) {
    //There is an error in request, if known, improve and retry
} catch (HttpServerErrorException hsee) {
    recvdStatusCode = hsee.getStatusCode();
    // Handle it within a switch case, if there is an option to retry.
}
  

Это может быть другой подход, я никогда не пробовал это сам-

 @Bean
  public RetryTemplate retryTemplate() {

    int maxAttempt = Integer.parseInt(env.getProperty("maxAttempt"));
    int retryTimeInterval = Integer.parseInt(env.getProperty("retryTimeInterval"));

    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(maxAttempt);

    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
    backOffPolicy.setBackOffPeriod(retryTimeInterval); // 1.5 seconds

    RetryTemplate template = new RetryTemplate();
    template.setRetryPolicy(retryPolicy);
    template.setBackOffPolicy(backOffPolicy);

    return template;
  }
  

// Вот вызов —

 retryTemplate.execute(context -> {
        System.out.println("inside retry method");
        ResponseEntity<?> requestData = RestTemplateProvider.getInstance().postAsNewRequest(bundle, ServiceResponse.class, serivceURL,
                CommonUtils.getHeader("APP_Name"));

        _LOGGER.info("Response ..."  requestData);
            throw new IllegalStateException("Something went wrong");
        });
  

Комментарии:

1. Не могу этого сделать … потому что я не хочу менять все свои методы обслуживания. Итак, мне в основном нужен способ определить e RestTemplate spring bean, настроенный для повторения этих вызовов

2. Это может быть другим способом решения ситуации —