[英]How implement a retry mechanism for restTemplate
我已经实现了一个 java 方法,它通过 Resttemplate 调用外部服务。 此外,我还在该方法中实现了一些额外的业务逻辑。 我如何为这些 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.