spring boot 接口限流 API限流 基于注解实现限流

一、代码实现

1.引入依赖

 <!--  springboot 整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 <!--  谷歌限流jar -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.自定义注解 CurrentLimitingAnnotation

 
/**
 * 自定义限流注解
 * @author sean
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentLimitingAnnotation {

    /**
     * 限流名称
     * @return
     */
    String name() default "";

    /**
     * 每秒限制访问次数
     * @return
     */
    double token() default 5;
}

3.接口测试

/**
 * @Author : sean
 * @DateTime : 2021/7/28、21:30
 * @Description :
 **/
@RestController
public class AopController {
    
     /**
     *  CurrentLimitingAnnotation token默认是5秒,这里设置1秒
     * @return
     */
    @GetMapping("/add")
    @CurrentLimitingAnnotation(name = "add", token = 1)
    public String add() {
        System.out.println("add.............");
        return "success";
    }
}

4.AOP 拦截注解实现限流

/**
 * @Author : sean
 * @DateTime : 2021/7/28、21:35
 * @Description : 全局拦截限流注解
 **/
@Aspect
@Component
public class CurrentLimitingAop {

    private ConcurrentHashMap<String, RateLimiter> rateLimiterConcurrentHashMap = new ConcurrentHashMap<>();

    @Around(value = "@annotation(com.sean.satoken.annotations.CurrentLimitingAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint) {

        try {
            // 获取拦截的方法名
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

            // 获取该方法的注解 CurrentLimitingAnnotation
            CurrentLimitingAnnotation currentLimitingAnnotation =
                    methodSignature.getMethod().getDeclaredAnnotation(CurrentLimitingAnnotation.class);

            //获取到注解的name,token
            String name = currentLimitingAnnotation.name();
            double token = currentLimitingAnnotation.token();

            //判断改名称是否有创建rateLimiter 没有则创建,有则拿来用
            RateLimiter rateLimiter = rateLimiterConcurrentHashMap.get(name);

            if (rateLimiter == null) {
                rateLimiterConcurrentHashMap.put(name, RateLimiter.create(token));
            }

            if (!rateLimiter.tryAcquire()) {
                return "请求过于频繁,请稍后再试";
            }

            return joinPoint.proceed();

        } catch (Throwable throwable) {
            return "系统错误!";
        }
    }
}

5.启动类

@SpringBootApplication
public class App {

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

6.测试

访问接口 ip:port/add,当前接口token设置了1秒,如果一秒内多次访问 return ”请求过于频繁,请稍后再试“

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值