如果主机离线,重试 java RestTemplate HTTP 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32352484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:24:04  来源:igfitidea点击:

Retry java RestTemplate HTTP request if host offline

javaspringapache-httpclient-4.xresttemplate

提问by Robert Moszczynski

Hi I'm using the spring RestTemplatefor calling a REST API. The API can be very slow or even offline. My application is building the cache by sending thousands of requests one after the other. The responses can be very slow too, because they contains a lot of data.

嗨,我正在使用 springRestTemplate来调用 REST API。API 可能非常慢,甚至离线。我的应用程序通过一个接一个地发送数千个请求来构建缓存。响应也可能非常缓慢,因为它们包含大量数据。

I have already increased the Timeout to 120 seconds. My problem now it that the API can be offline and I get a org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from poolexception.

我已经将超时增加到 120 秒。我现在的问题是 API 可以脱机,并且出现org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool异常。

In the case when the API ist offline, the application should wait and try again until the API is online again.

在 API 离线的情况下,应用程序应等待并重试,直到 API 再次在线。

Can I achieve this in RestTemplateout of the box without building exception-loops on my own?

我可以在RestTemplate不自行构建异常循环的情况下开箱即用地实现这一点吗?

Thanks!

谢谢!

回答by Rafal G.

Use Spring Retry project (https://dzone.com/articles/spring-retry-ways-integrate, https://github.com/spring-projects/spring-retry).

使用 Spring Retry 项目(https://dzone.com/articles/spring-retry-ways-integratehttps://github.com/spring-projects/spring-retry)。

It is designed to solve problems like yours.

它旨在解决像您这样的问题。

回答by Devender Kumar

I had same situation and done some googling found the solution. Giving answer in hope it help someone else. You can set max try and time interval for each try.

我遇到了同样的情况并做了一些谷歌搜索找到了解决方案。给出答案,希望对其他人有所帮助。您可以为每次尝试设置最大尝试次数和时间间隔。

@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;
  }

And my rest service that i want to execute is below.

我要执行的休息服务如下。

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");
        });

回答by cheffe

You can also tackle this annotation-driven using Spring Retry. This way you will avoid to implement the template.

您还可以使用 Spring Retry 来解决这个注解驱动的问题。这样您就可以避免实施模板。

Add it to your pom.xml

将它添加到你的 pom.xml

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

Enable it for your application/configuration

为您的应用程序/配置启用它

@SpringBootApplication
@EnableRetry
public class MyApplication {
  //...
}

Guard methods that are in danger of failure with @Retryable

保护有失败危险的方法 @Retryable

@Service
public class MyService {

  @Retryable(maxAttempts=5, value = RuntimeException.class, 
             backoff = @Backoff(delay = 15000, multiplier = 2))
  public List<String> doDangerousOperationWithExternalResource() {
     // ...
  }

}