Spring Boot使用Retry机制实现失败重试
在实际应用过程中,我们时常会遇到需要重试的机制。例如发送短信的时候,发送失败一次后需要再次发起第二次或者第三次重试,常规的思路就是记录当前短信对应的发送失败次数,当小于三次且均为失败时就发起请求。这里我们介绍一种极为方便的重试机制,springboot下整合retry。一. 使用场景发送短信请求,若失败则需要再次发起请求,若一直失败则需要满足达到了两次重试请求。若不引入任何重试机制,我们的实现逻辑
在实际应用过程中,我们时常会遇到需要重试的机制。例如发送短信的时候,发送失败一次后需要再次发起第二次或者第三次重试,常规的思路就是记录当前短信对应的发送失败次数,当小于三次且均为失败时就发起请求。这里我们介绍一种极为方便的重试机制,springboot下整合retry。
一. 使用场景
发送短信请求,若失败则需要再次发起请求,若一直失败则需要满足达到了两次重试请求。
若不引入任何重试机制,我们的实现逻辑大体如下,记录短信唯一标识以及对应的请求历史和请求结果,若失败则累加失败次数,直到某一次成功了,或者重试次数达到了三次。
这里我们需要引入数据库来记录失败次数,以及增加数据库请求,有没有一种更方便的方式来实现呢,答案是有的。
二. Retry机制
这里我们以SpringBoot为例:
-
首先我们引入相关pom依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> </dependencies>
-
在启动类上加上注解@EnableRetry
@SpringBootApplication @EnableRetry public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
-
定义Controller层:这里我们把下层异常进行throws抛出,或者我们进行try,catch;否则重试机制将会不生效。
@RestController public class HelloController { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private SmsService smsService; @GetMapping("/sendSms") public void sendSms(@RequestParam String phoneNumber, @RequestParam String content) throws Exception{ boolean isSuccess = smsService.sendSms(phoneNumber, content); if(isSuccess){ logger.info("短信发送成功"); }else{ logger.error("短信发送失败"); } } }
-
定义Service
@Service public class SmsService { private Logger logger = LoggerFactory.getLogger(getClass()); @Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5)) public boolean sendSms(String phoneNumber, String content) throws Exception{ // 模拟短信发送失败 throw new Exception("短信发送失败"); } }
-
解释@Retryable注解
value:表示遇到何种异常情况下需要重试
maxAttempts:表示最大重试次数
delay:表示重试的延迟时间(毫秒计数)
multiplier:表示上一次延迟时间为本次的倍数
以上就是我们实现的简单重试机制示例,相较于记录失败次数并发起重试,这种方式是不是简单又优雅,第一次看到这种实现方法的时候笔者也被惊艳到了,若在实际业务开发过程中需要使用重试机制,我们可以借鉴该种实现思路。
三. 拓展
若在@Retryable设置的最大重试次数下,还是没有成功,我们需要回调另一个方法,那我们该如何实现。
这里我们引入@Recover注解。
我们在sendSms的Service类中,加上以下代码:
@Recover
public void recover(Exception e){
logger.warn("发送短信失败!!!");
//记日志到数据库
}
我们再进行测试,就会发现,当我们达到最大重试3次后,若还是失败则会执行该代码块。
参考资料:
更多推荐
所有评论(0)