springboot整合spring retry 重试机制

Easter79
• 阅读 676

当我们调用一个接口可能由于网络等原因造成第一次失败,再去尝试就成功了,这就是重试机制,spring支持重试机制,并且在Spring Cloud中可以与Hystaix结合使用,可以避免访问到已经不正常的实例。 但是切记非幂等情况下慎用重试

一  加入依赖

 <!-- 重试机制 -->
    <dependency>
      <groupId>org.springframework.retry</groupId>
      <artifactId>spring-retry</artifactId>
    </dependency>

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

二 在主类上加入 @EnableRetry 注解

@EnableRetry   //开启重试机制
@EnableAutoConfiguration //开启自动配置
@SpringBootApplication
public class WjKekingApplication {

  public static void main(String[] args) {
    SpringApplication.run(WjKekingApplication.class, args);
  }
}

三 demo

package com.wj.project.keking.myTest.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.time.LocalTime;

@Service
public class RetryService {

    private final static Logger logger = LoggerFactory.getLogger(RetryService.class);

    private final int totalNum = 100000;

    /**
     * @Retryable的参数说明: •value:抛出指定异常才会重试
     * •include:和value一样,默认为空,当exclude也为空时,默认所以异常
     * •exclude:指定不处理的异常
     * •maxAttempts:最大重试次数,默认3次
     * •backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
     */
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
    public int retry(int num) {
        logger.info("减库存开始" + LocalTime.now());
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            logger.error("illegal");
        }
        if (num <= 0) {
            throw new IllegalArgumentException("数量不对");
        }
        logger.info("减库存执行结束" + LocalTime.now());
        return totalNum - num;
    }

    @Recover
    public void recover(Exception e) {
        logger.warn("减库存失败!!!" + LocalTime.now());
    }


}

四 写一个简单的测试

import base.BaseTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class RetryServiceTest extends BaseTest {

    @Autowired
    private RetryService retryService;

    @Test
    public void retry() {
        int count = retryService.retry(-1);
        System.out.println("库存为 :" + count);
    }
}

五 结果:

2018-07-28 01:12:09.836  INFO 31128 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 55413 (http) with context path ''
2018-07-28 01:12:09.843  INFO 31128 --- [           main] c.w.p.k.myTest.service.RetryServiceTest  : Started RetryServiceTest in 7.178 seconds (JVM running for 10.657)
2018-07-28 01:12:10.584  INFO 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : 减库存开始01:12:10.584
2018-07-28 01:12:10.584 ERROR 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : illegal
2018-07-28 01:12:12.588  INFO 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : 减库存开始01:12:12.588
2018-07-28 01:12:12.588 ERROR 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : illegal
2018-07-28 01:12:15.588  INFO 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : 减库存开始01:12:15.588
2018-07-28 01:12:15.588 ERROR 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : illegal
2018-07-28 01:12:15.589  WARN 31128 --- [           main] c.w.p.k.myTest.service.RetryService      : 减库存失败!!!01:12:15.589
库存为 :100000
2018-07-28 01:12:15.604  INFO 31128 --- [       Thread-3] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@1af2d44a: startup date [Sat Jul 28 01:12:03 CST 2018]; root of context hierarchy
2018-07-28 01:12:15.608  INFO 31128 --- [       Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'taskExecutor'
’

六 注意事项:

1、使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效。也就是要标记为@Service,然后在其它类使用@Autowired注入或者@Bean去实例才能生效。

2 、要触发@Recover方法,那么在@Retryable方法上不能有返回值,只能是void才能生效。

3 、非幂等情况下慎用

4 、使用了@Retryable的方法里面不能使用try...catch包裹,要在方法上抛出异常,不然不会触发。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Stella981 Stella981
3年前
Spring RabbitMQ 消息重试机制
RabbitMQ框架提供了重试机制,只需要简单的配置即可开启,可以提升程序的健壮性。测试一:重试5次spring:rabbitmq:listener:simple:retry:enabled:true
Wesley13 Wesley13
3年前
Java之Retry重试机制详解
应用中需要实现一个功能:需要将数据上传到远程存储服务,同时在返回处理成功情况下做其他操作。这个功能不复杂,分为两个步骤:第一步调用远程的Rest服务上传数据后对返回的结果进行处理;第二步拿到第一步结果或者捕捉异常,如果出现错误或异常实现重试上传逻辑,否则继续接下来的功能业务操作。常规解决方案trycatchredo简单重试
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k