【SpringBoot】springboot使用RestTemplate 进行http请求失败自动重试

前言

我们的服务需要调用别人的接口,由于对方的接口服务不是很稳定,经常超时,于是需要增加一套重试逻辑。这里使用 Spring Retry 的方式来实现。

一、引入POM

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

<dependency>
       <groupId>org.springframework.retry</groupId>
       <artifactId>spring-retry</artifactId>
       <scope>test</scope>
</dependency>

二、 修改启动类

在Spring Boot 应用入口启动类,也就是配置类的上面加上@EnableRetry 注解,表示让重试机制生效。

【SpringBoot】springboot使用RestTemplate 进行http请求失败自动重试_第1张图片

@EnableRetry
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
    @Bean
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiApplication.class, args);
    }
}

注意:

我这里还注入了Bean,因为在启动项目是会报错。

@Bean
RestTemplate restTemplate(){
     return new RestTemplate();
 }

报错信息:

Field restTemplate in com.cloud.ribbon_consumer.project.service.HelloService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.

问题原因:

Spring Boot 1.3版本中,会默认提供一个RestTemplate的实例Bean,而在 Spring Boot 1.4以及以后的版本中,这个默认的bean不再提供了,我们需要在Application启动时,手动创建一个RestTemplate的配置。

这样,我们在类中通过注解 @Autowired 使用 TestTemplate 的时候,程序就可以找到被实例化的 TestTemplate,就不会出现上述的报错了。

三、具体使用

写一个模拟的业务类RetryService ,在其里面注入RestTemplate 。

@Service
public class RetryService {
    private static Logger log = LoggerFactory.getLogger(RetryService.class);

    @Resource
    private RestTemplate restTemplate;

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


    @Retryable(value = RestClientException.class, maxAttempts = 3,
            backoff = @Backoff(delay = 5000L,multiplier = 2))
    public String getRequest(String address) {
        log.info("发起远程API 地址: {} ,请求事件: {}", address, DATE_TIME_FORMATTER.format(LocalDateTime.now()));

        ResponseEntity<String> responseEntity
                = restTemplate.getForEntity(address, String.class);

        // 获取响应结果
        return responseEntity.getBody();
    }
}
  1. @Retryable注解的方法在发生异常时会重试,参数说明:
  • value:当指定异常发生时会进行重试 ,HttpClientErrorException是RestClientException的子类。
  • include:和value一样,默认空。如果 exclude也为空时,所有异常都重试
  • exclude:指定异常不重试,默认空。如果 include也为空时,所有异常都重试
  • maxAttemps:最大重试次数,默认3
  • backoff:重试等待策略,默认空
  1. @Backoff注解为重试等待的策略,参数说明:
  • delay:指定重试的延时时间,默认为1000毫秒
  • multiplier:指定延迟的倍数,比如设置delay=5000,multiplier=2时,第一次重试为5秒后,第二次为10(5x2)秒,第三次为20(10x2)秒。

四、测试

我这里写了一个不存在的服务,用于测试重试机制

 @GetMapping(value = "/update1")
    public String updatePingTai1() {
        String request = retryService.getRequest("http://127.0.0.1:3214");
        return request);
    }

在这里插入图片描述

这里可以看到我们是重试了三次,才抛出的异常。

参考:

  1. https://www.cnblogs.com/zimug/p/13507850.html
  2. https://www.cnblogs.com/liuyupen/p/13957171.html#%E6%96%B9%E5%BC%8F%E5%9B%9Bspring-%E8%87%AA%E5%B8%A6%E9%87%8D%E8%AF%95%E5%B7%A5%E5%85%B7
  3. https://www.cnblogs.com/liuyupen/p/13957171.html#%E6%96%B9%E5%BC%8F%E5%9B%9Bspring-%E8%87%AA%E5%B8%A6%E9%87%8D%E8%AF%95%E5%B7%A5%E5%85%B7

你可能感兴趣的:(springboot,spring,boot,http,java)