如何配置 RestTemplate 以在特定响应状态码时重试调用?

huangapple go评论75阅读模式
英文:

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(&quot;maxAttempt&quot;));
    int retryTimeInterval = Integer.parseInt(env.getProperty(&quot;retryTimeInterval&quot;));

    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 -&gt; {
        System.out.println(&quot;inside retry method&quot;);
        ResponseEntity&lt;?&gt; requestData = RestTemplateProvider.getInstance().postAsNewRequest(bundle, ServiceResponse.class, serivceURL,
                CommonUtils.getHeader(&quot;APP_Name&quot;));

        _LOGGER.info(&quot;Response ...&quot;+ requestData);
            throw new IllegalStateException(&quot;Something went wrong&quot;);
        });

huangapple
  • 本文由 发表于 2020年10月6日 19:38:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/64225045.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定