英文:
How to set up RestTemplate to retry calls on certain response status code?
问题
我在设置RestTemplate以重试远程调用时遇到了问题。有人知道如何配置RestTemplate在收到503响应状态码后重试调用吗?
英文:
I’ve trouble setting up a RestTemplate to retry remote calls. Does anyone know how to configure the RestTemplate to retry calls after getting 503 response status code?
答案1
得分: 4
是的,这是可能的,你可以尝试自定义重试策略。
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) {
                    // 对于状态码为503的情况
                    if (((HttpServerErrorException) classifiable).getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE) {
                        return simpleRetryPolicy;
                    }
                    return new NeverRetryPolicy();
                }
                return new NeverRetryPolicy();
            }
        });
    }
}
然后可以如下简单调用:
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new InternalServerExceptionClassifierRetryPolicy());
英文:
Yes it is possible, you can try out custom retry policy.
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();
		}
	});
}}
Ans the simply call it as below:
RetryTemplate template = new RetryTemplate();
template.setRetryPolicy(new InternalServerExceptionClassifierRetryPolicy())
答案2
得分: 0
Retry within the catch block
try {
    responseEntity = restTemplate.exchange(endpoint, HttpMethod.POST, entity, MyResponse.class);
} catch (HttpClientErrorException hcee) {
    //请求存在错误,如果已知错误,改进并重试
} catch (HttpServerErrorException hsee) {
    recvdStatusCode = hsee.getStatusCode();
    // 在 switch case 内处理,如果有重试选项的话
}
这可能是另一种方法,我自己从未尝试过-
@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秒
    RetryTemplate template = new RetryTemplate();
    template.setRetryPolicy(retryPolicy);
    template.setBackOffPolicy(backOffPolicy);
    return template;
}
//以下是调用方法-
retryTemplate.execute(context -> {
    System.out.println("在重试方法内部");
    ResponseEntity<?> requestData = RestTemplateProvider.getInstance().postAsNewRequest(bundle, ServiceResponse.class, serivceURL,
            CommonUtils.getHeader("APP_Name"));
    _LOGGER.info("响应 ..." + requestData);
    throw new IllegalStateException("出现了问题");
});
英文:
Retry within the catch block
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.
}
> This may be another approach, I have never tried this myself-
@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;
  }
//Here is the invocation -
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");
        });
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论