调用第三方接口太麻烦了!推荐一款超好用的重试框架,一个注解就能搞定,简洁优雅(带私活)

最近要做的一个需求,需要调用第三方接口。正常情况下,接口的响应是符合要求的,只有在网络抖动等极少数的情况下,会存在超时情况。因为是小概率事件,所以一次超时之后,进行一次重试操作应该就可以了。同事提交了代码,让我做 code review。代码差不多是这样的:

@Controller
public class RetryController {
    @Autowired
    private RetryRequestService retryRequestService;

    public String doSth(String param) {
        int count = 0;
        String result = "";
        while (count < 3) {
            try {
                result = retryRequestService.request(param);
                break;
            } catch (Exception e) {
                count++;
            }
        }
        return "响应是" + result;
    }
}

我看完之后,感觉通过固定次数的循环来实现重试,虽然功能实现了,但是不够简洁呀,对原有代码逻辑的侵入性太强了。于是我给同事推荐了超好用的重试框架,spring-retry。

简介与快速接入

spring-retry 是 Spring 全家桶中提供的开源重试框架,如果你用的是 Spring Boot 项目,那么接入起来会非常简单,只需要三步即可实现快速接入。

第一步,引入依赖

<!--springboot项目都不用引入版本号-->
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
<!--还是需要aop的支持的-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
</dependency>

第二步,在启动类上加注解 @EnableRetry

此举是让你的 Spring Boot 项目支持 spring-retry 的重试功能。像这样:

@SpringBootApplication
@EnableRetry
public class ApplicationServer {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationServer.class, args);
        System.out.println("startApp success!");
    }
}

第三步,在需要重试的方法上加注解 @Retryable

如开头所说,我们需要重试的方法是RetryRequestService#request这个方法。那么我们就在这个方法上加@Retryable注解。如下:

@Service
@Slf4j
public class RetryRequestService {
    @Autowired
    private OtherSystemSpi otherSystemSpi;

    @Retryable(value = RuntimeException.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
    public String request(String param) {
        double random = Math.random();
        log.info("请求进来了,随机值为:" + random);
        if (random > 0.1) {
            throw new RuntimeException("超时");
        }
        return otherSystemSpi.request(param);
    }
}

当然,我们这里写了个调皮的逻辑来模拟超时。如果随机值大于0.1则抛出一个RuntimeException异常。每次请求进来时都会输出日志。

我来解释一下@Retryable注解中的信息。

  • value = RuntimeException.class:是指方法抛出RuntimeException异常时,进行重试。这里可以指定你想要拦截的异常。

  • maxAttempts:是最大重试次数。如果不写,则是默认 3 次。

  • backoff = @Backoff(delay = 100):是指重试间隔。delay=100 意味着下一次的重试,要等 100 毫秒之后才能执行。

我们来执行一下,可以看到日志输出:

2022-03-15 23:51:19.762  INFO 3343 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.11030214774098712
2022-03-15 23:51:19.867  INFO 3343 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.09624689154608002

前两次的随机值都大于 0.1,所以进行了重试,而且注意时间,都是间隔了大概 100 毫秒输出的日志。第三次的随机值小于 0.1,就直接返回了。

我又试了几次,使五次请求的随机值都大于 0.1 ,则结果是进行了五次请求,最后抛出了个异常。

2022-03-15 23:52:58.201  INFO 3449 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.5265644192525288
2022-03-15 23:52:58.303  INFO 3449 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.6343538744876432
2022-03-15 23:52:58.407  INFO 3449 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.5482463853575078
2022-03-15 23:52:58.511  INFO 3449 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.5624923285641071
2022-03-15 23:52:58.616  INFO 3449 --- [main] c.o.service.retry.RetryRequestService  : 请求进来了,随机值为:0.305945622979098
Exception in thread "main" java.lang.RuntimeException: 超时
        at com.opensource.service.retry.RetryRequestService.request(RetryRequestService.java:24)
        at com.opensource.service.retry.RetryRequestService$$FastClassBySpringCGLIB$$50f0bdca.invoke(<generated>)

总结

怎么样,spring-retry 的接入和使用是不是非常简单?只需要一个注解,就可以省去你自己写的复杂的重试代码,方便省心。而且它还支持重试间隔时间随机等更多的功能,需要大家自己探索啦。

今天就分享到这里,开源项目的地址放下面啦~

GitHub - spring-projects/spring-retry

写在最后(私活源码)

项目介绍

Jeepay是一套适合互联网企业使用的开源支付系统,支持多渠道服务商和普通商户模式。已对接微信支付,支付宝,云闪付官方接口,支持聚合码支付。

Jeepay使用Spring Boot和Ant Design Vue开发,集成Spring Security实现权限管理功能,是一套非常实用的web开发框架。

项目特点

· 支持多渠道对接,支付网关自动路由

· 已对接微信服务商和普通商户接口,支持V2和V3接口

· 已对接支付宝服务商和普通商户接口,支持RSA和RSA2签名

· 已对接云闪付服务商接口,可选择多家支付机构

· 提供http形式接口,提供各语言的sdk实现,方便对接

· 接口请求和响应数据采用签名机制,保证交易安全可靠

· 系统安全,支持分布式部署,高并发

· 管理端包括运营平台和商户系统

· 管理平台操作界面简洁、易用

· 支付平台到商户系统的订单通知使用MQ实现,保证了高可用,消息可达

· 支付渠道的接口参数配置界面自动化生成

· 使用spring security实现权限管理

· 前后端分离架构,方便二次开发

· 由原XxPay团队开发,有着多年支付系统开发经验

系统架构

Jeepay计全支付系统架构图

图片

核心技术栈

软件名称

描述

版本

Jdk

Java环境

1.8

Spring Boot

开发框架

2.4.5

Redis

分布式缓存

3.2.8 或 高版本

MySQL

数据库

5.7.X 或 8.0 高版本

MQ

消息中间件

ActiveMQ 或 RabbitMQ 或 RocketMQ

Ant Design Vue

Ant Design的Vue实现,前端开发使用

2.1.2

MyBatis-Plus

MyBatis增强工具

3.4.2

WxJava

微信开发Java SDK

4.1.0

Hutool

Java工具类库

5.6.6

开发部署

· 系统开发:https://docs.jeequan.com/docs/jeepay/dev_serv

· 通道对接:https://docs.jeequan.com/docs/jeepay/dev_channel

· 线上部署:https://docs.jeequan.com/docs/jeepay/deploy

· 接口文档:https://docs.jeequan.com/docs/jeepay/payment_api

功能模块

Jeepay运营平台功能

图片

Jeepay商户系统功能

图片

系统截图

以下截图是从实际已完成功能界面截取

图片

图片

图片

图片

图片

图片

图片

图片

开源地址

扫码关注本号,后台回复 支付

扫码关注本号,后台回复 支付

持续关注本号,分享更多项目源码

  • 32
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值