簡體   English   中英

如何實現restTemplate的重試機制

[英]How implement a retry mechanism for restTemplate

我已經實現了一個 java 方法,它通過 Resttemplate 調用外部服務。 此外,我還在該方法中實現了一些額外的業務邏輯。 我如何為這些 rest 調用實現重試機制。 還需要考慮以下幾點。

  1. 我無法為整個方法添加重試。
  2. 最好為 rest 調用添加重試(通過 resttemplate)。
  3. 應該有一種方法可以禁用不需要的 rest 呼叫的重試選項。

您可以在HttpClient中添加重試機制並將其用於RestTemplate ,如下所示:

@Bean
public ClientHttpRequestFactory clientFactory() {
    HttpClient httpClient = HttpClients.custom()            
        .setRetryHandler((exception, executionCount, context) -> {
            if (executionCount > 3) {
                log.warn("Maximum retries {} reached", 3);
                return false;
            }
            if (<some condition for retry>) {
                log.warn("Retry {}", executionCount);
                return true;
            }
            return false;
        })
        .build();

    return new HttpComponentsClientHttpRequestFactory(httpClient);
}
@Bean
public RestTemplate customRestTemplate(@Qualifier("clientFactory") ClientHttpRequestFactory clientFactory){ 
    return new RestTemplate(clientFactory);
}

Spring 提供了帶有@Retry注解的重試機制。 您必須使用以下依賴項。

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.1.5.RELEASE</version>
</dependency>

Spring 提供以下注解。

Spring 重試注解

@EnableRetry – 在 spring 引導項目中啟用 spring 重試

@Retryable – 表示任何方法都可以重試

@Recover – 指定回退方法

我在下面提供示例代碼。

@Configuration
@EnableRetry
@SpringBootApplication
public class MyApplication {
}

您可以參考完整的示例以了解更多信息。

你可以自己控制它做這樣的事情:

public void method() {
    RestTemplate rest = new RestTemplate();
    int retries = 0;
    boolean done = false;

    // first call 
    while (!done && retries < 5) {
        try {
            rest.exchange(..);
            done = true;
        } catch(RestClientResponseException e) {
            retries++;
            log.info("Retrying..");
        }
    }

    done = false;
    retries = 0;

    // Business logic 1

    // second call
    while (!done && retries < 5) {
        try {
            rest.exchange(..);
            done = true;
        } catch(RestClientResponseException e) {
            retries++;
            log.info("Retrying..");
        }
    }

    // Business logic 2
}

對於 rest api 呼叫,您可以在實際 rest 呼叫進行的客戶端級別實施重試機制

 @Retryable(value = Exception.class, maxAttemptsExpression = "${retry.maxAttempts}", backoff = @Backoff(delayExpression = "${retry.maxDelay}"))
    public Optional<T> getApiCall(String url, String token, Class<T> resClass) {
        ResponseEntity<T> response = null;
        try {
            logger.info(url);
            // create headers
            HttpHeaders headers = new HttpHeaders();
            // set `accept` header
            headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
            headers.setBearerAuth(token);
            // set custom header
            // headers.set("x-request-src", "desktop");
            // build the request
            HttpEntity<String> entity = new HttpEntity<>("", headers);
            // use exchange method for HTTP call
            try {
                response = this.restTemplate.exchange(url, HttpMethod.GET, entity, resClass, 1);
            } catch (HttpStatusCodeException e) {
                return errorService.throwException(HttpStatus.NOT_FOUND, EKDError.LIFPRO406);
            }
            if (response.getStatusCode() == HttpStatus.OK) {
                return Optional.ofNullable(response.getBody());
            } else {
                return errorService.throwException(HttpStatus.NOT_FOUND, EKDError.LIFPRO406);
            }
        } catch (HttpClientErrorException | HttpServerErrorException e) {
            logger.error("Exception in api call : ", e);
            return errorService.throwException(HttpStatus.INTERNAL_SERVER_ERROR, EKDError.LIFPRO407);
        }
    }

現在最大嘗試和延遲是可配置的設置 application.properties maxAttemptsExpression = "${retry.maxAttempts}", backoff = @Backoff(delayExpression = "${retry.maxDelay}"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM