springboot整合spring retry 重试机制

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

一  加入依赖

1 <!-- 重试机制 --> 2 <dependency> 3 <groupId>org.springframework.retry</groupId> 4 <artifactId>spring-retry</artifactId> 5 </dependency> 6 7 <dependency> 8 <groupId>org.aspectj</groupId> 9 <artifactId>aspectjweaver</artifactId> 10 </dependency>

二 在主类上加入 @EnableRetry 注解

1@EnableRetry //开启重试机制 2@EnableAutoConfiguration //开启自动配置 3@SpringBootApplication 4public class WjKekingApplication { 5 6 public static void main(String[] args) { 7 SpringApplication.run(WjKekingApplication.class, args); 8 } 9}

三 demo

1package com.wj.project.keking.myTest.service; 2 3import org.slf4j.Logger; 4import org.slf4j.LoggerFactory; 5import org.springframework.retry.annotation.Backoff; 6import org.springframework.retry.annotation.Recover; 7import org.springframework.retry.annotation.Retryable; 8import org.springframework.stereotype.Service; 9 10import java.time.LocalTime; 11 12@Service 13public class RetryService { 14 15 private final static Logger logger = LoggerFactory.getLogger(RetryService.class); 16 17 private final int totalNum = 100000; 18 19 /** 20 * @Retryable的参数说明: •value:抛出指定异常才会重试 21 * •include:和value一样,默认为空,当exclude也为空时,默认所以异常 22 * •exclude:指定不处理的异常 23 * •maxAttempts:最大重试次数,默认3次 24 * •backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。 25 */ 26 @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5)) 27 public int retry(int num) { 28 logger.info("减库存开始" + LocalTime.now()); 29 try { 30 int i = 1 / 0; 31 } catch (Exception e) { 32 logger.error("illegal"); 33 } 34 if (num <= 0) { 35 throw new IllegalArgumentException("数量不对"); 36 } 37 logger.info("减库存执行结束" + LocalTime.now()); 38 return totalNum - num; 39 } 40 41 @Recover 42 public void recover(Exception e) { 43 logger.warn("减库存失败!!!" + LocalTime.now()); 44 } 45 46 47}

四 写一个简单的测试

1import base.BaseTest; 2import org.junit.Test; 3import org.springframework.beans.factory.annotation.Autowired; 4 5public class RetryServiceTest extends BaseTest { 6 7 @Autowired 8 private RetryService retryService; 9 10 @Test 11 public void retry() { 12 int count = retryService.retry(-1); 13 System.out.println("库存为 :" + count); 14 } 15}

五 结果:

12018-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 '' 22018-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) 32018-07-28 01:12:10.584 INFO 31128 --- [ main] c.w.p.k.myTest.service.RetryService : 减库存开始01:12:10.584 42018-07-28 01:12:10.584 ERROR 31128 --- [ main] c.w.p.k.myTest.service.RetryService : illegal 52018-07-28 01:12:12.588 INFO 31128 --- [ main] c.w.p.k.myTest.service.RetryService : 减库存开始01:12:12.588 62018-07-28 01:12:12.588 ERROR 31128 --- [ main] c.w.p.k.myTest.service.RetryService : illegal 72018-07-28 01:12:15.588 INFO 31128 --- [ main] c.w.p.k.myTest.service.RetryService : 减库存开始01:12:15.588 82018-07-28 01:12:15.588 ERROR 31128 --- [ main] c.w.p.k.myTest.service.RetryService : illegal 92018-07-28 01:12:15.589 WARN 31128 --- [ main] c.w.p.k.myTest.service.RetryService : 减库存失败!!!01:12:15.589 10库存为 :100000 112018-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 122018-07-28 01:12:15.608 INFO 31128 --- [ Thread-3] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'taskExecutor' 13

六 注意事项:

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

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

3 、非幂等情况下慎用

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )