程序重试,简单重试和优雅重试 之 Spring Retry 简单使用

总结:有时候程序会出现各种错误,比如网络抖动,链接超时,或者其他的一些情况,为了增加成功的机会,出错时候多重试几次 在业务允许的情况呀,提高成功的概率,那么重试尤为重要了,比如我就遇到过,接口返回下载链接 而根据下载链接 却下载不到 对应的文件(那是调用别人的开发票接口(怀疑他们是异步生成文件的)),还有发邮件也是 发失败的情况 肯定存在,这时候重试 尤为重要。

话不多说代码如下:

简单自己写例子1:

	@Test
	public void sendRetry1() {
		for (int i = 0; i < 3; i++) {
			try {
				//模拟业务
				System.out.println("重试次数"+i);
				if(i == 0){//模拟出错
					throw new RuntimeException("出错了");
				}
				//如果成功 直接 return 跳出循环
				//简单延时
				Thread.sleep(1000*(i-1));
			}catch (Exception e){

			}
		}
	}

  例子2,优雅实现 spring Retry 这里是springboot

   2.1  引入pom

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

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

2.2 开启注解

@SpringBootApplication
@EnableSwagger2
@EnableRetry   //开启重试机制
public class DemoApplication {

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


}

  2.3 开始使用

@Service
public class RetryService {

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

    private final int totalNum = 100000;

    /**
     * 1、使用了@Retryable的方法不能在本类被调用,不然重试机制不会生效(动态代理),然后在其它类使用@Autowired注入或者@Bean去实例才能生效。

     2 、要触发@Recover方法,重试几次失败后 调用

     3 、非幂等情况下慎用

     4 、使用了@Retryable的方法里面不能使用try...catch包裹,要在方法上抛出异常,不然不会触发。
     *
     * @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("捕获异常不会触发");
        }
        if (num <= 0) {
            throw new RuntimeException("数量不对");
        }
        logger.info("重试测试结束" + LocalTime.now());
        return totalNum - num;
    }

    @Recover
    public int recover(Exception e) {
        logger.info("重试测试几次失败!!!" + LocalTime.now());
        return 2;
    }


}

  2.4 调用

	@Autowired
	private RetryService retryService;
	@Test
	public void sendRetry() {
		retryService.retry(0);
	}

  

posted @ 2019-06-17 14:01  川流不息&  阅读(941)  评论(0编辑  收藏  举报