使用guava实现接口限流

使用guava实现接口限流

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.3.5.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <modelVersion>4.0.0</modelVersion>
?
   <artifactId>apiLimit</artifactId>
?
   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>com.google.guava</groupId>
           <artifactId>guava</artifactId>
           <version>30.1.1-jre</version>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-aop</artifactId>
       </dependency>
       <dependency>
           <groupId>org.aspectj</groupId>
           <artifactId>aspectjweaver</artifactId>
           <version>1.9.1</version>
       </dependency>
   </dependencies>
</project>

限流注解

package com.cyz.annocation;
?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
/**
* @Author lian-chen
* @Date 2021/7/23 8:19
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLianChenLimit {
   /**
    * 限流的名称
    *
    * @return
    */
   String name() default "";
?
   /**
    * 限制次数 每秒
    */
   double token() default 20;
}

AOP通知

package com.cyz.aop;
?
import com.cyz.annocation.MyLianChenLimit;
import com.google.common.util.concurrent.RateLimiter;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
?
import java.util.concurrent.ConcurrentHashMap;
?
/**
* @Author lian-chen
* @Date 2021/7/23 8:25
*/
@Aspect
@Component
public class CurrentLimitAop {
?
   /**
    * 存放每一个方法对应的 RateLimiter
    */
   private ConcurrentHashMap<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();
?
   @Before(value = "@annotation(com.cyz.annocation.MyLianChenLimit)")
   public void before() {
       System.out.println("前置通知......");
  }
?
   /**
    * 只要方法上有加上自定义的限流注解,就会被aop环绕通知
    *
    * @param joinPoint 切入点
    * @return
    */
   @Around(value = "@annotation(com.cyz.annocation.MyLianChenLimit)")
   public Object around(ProceedingJoinPoint joinPoint) {
       /**
        * 拦截目标方法
        */
       try {
           /**
            * 获取拦截的方法名
            */
           Signature signature = joinPoint.getSignature();
           MethodSignature methodSignature = (MethodSignature) signature;
?
           /**
            * 获取方法注解的参数
            */
           MyLianChenLimit myLianChenLimit = methodSignature.getMethod().getDeclaredAnnotation(MyLianChenLimit.class);
           String name = myLianChenLimit.name();
           double token = myLianChenLimit.token();
?
           /**
            * 获取或创建对应的 RateLimiter
            */
           RateLimiter rateLimiter = rateLimiterMap.get(name);
           if (rateLimiter == null) {
               /**
                * 没秒生成对应个数的token
                */
               rateLimiter = RateLimiter.create(token);
上一篇:快速下载vscode的方法


下一篇:MySQL List分区(三)