美文网首页
AOP+ RateLimiter单机限流

AOP+ RateLimiter单机限流

作者: 香沙小熊 | 来源:发表于2020-06-13 16:24 被阅读0次

    1.添加依赖

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-aop</artifactId>
                </dependency>
    

    启动类上添加注解

    @EnableAspectJAutoProxy(proxyTargetClass=true)
    

    2.AOP类

    /**
     * @author xionghu
     * @date 2020/6/13 10:32
     * @desc 配置限流切面
     */
    @Aspect
    @Scope
    @Component
    public class RateLimiterAspect {
        private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
        private final ConcurrentMap<String, RateLimiter> RATE_LIMITER_CACHE = new ConcurrentHashMap<>();
    
        @Pointcut(value = "@annotation(com.ihuaben.bridge.web.ratelimiter.ApiRateLimiter)")
        public void rateLimit() {
    
        }
    
        @Around("rateLimit()")
        public Object pointcut(ProceedingJoinPoint point) throws Throwable {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            // 通过 AnnotationUtils.findAnnotation 获取 RateLimiter 注解
            ApiRateLimiter rateLimiter = AnnotationUtils.findAnnotation(method, ApiRateLimiter.class);
    
            if (rateLimiter == null) {
                return point.proceed();
            }
            if (rateLimiter.qps() > ApiRateLimiter.NOT_LIMITED) {
                double qps = rateLimiter.qps();
                if (RATE_LIMITER_CACHE.get(method.getName()) == null) {
                    // 初始化 QPS
                    RATE_LIMITER_CACHE.put(method.getName(), RateLimiter.create(qps));
                }
    
                log.debug("[{}]的QPS设置为: {}", method.getName(), RATE_LIMITER_CACHE.get(method.getName()).getRate());
                // 尝试获取令牌
                if (RATE_LIMITER_CACHE.get(method.getName()) != null && !RATE_LIMITER_CACHE.get(method.getName()).tryAcquire(rateLimiter.timeout(), rateLimiter.timeUnit())) {
                    throw new BusinessException(EmBusinessError.RATELIMIT);
                }
            }
            return point.proceed();
        }
    
    }
    
    import org.springframework.core.annotation.AliasFor;
    import java.lang.annotation.*;
    import java.util.concurrent.TimeUnit;
    /**
     * @author xionghu
     * @date 2020/6/13 10:32
     * @desc 创建限流限制
     */
    @Target({ElementType.PARAMETER, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface ApiRateLimiter {
    
    
        int NOT_LIMITED = 0;
    
        /**
         * qps
         */
        @AliasFor("qps") double value() default NOT_LIMITED;
    
        /**
         * qps
         */
        @AliasFor("value") double qps() default NOT_LIMITED;
    
        /**
         * 超时时长
         * 默认间隔1s时间
         */
        int timeout() default 1000;
    
        /**
         * 超时时间单位
         */
        TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    }
    

    3.AOP类

    @RestController
    @RequestMapping({ "/admin" })
    public class TestController extends BaseController {
    
        @RequestMapping({ "/hello" })
        @ApiRateLimiter(value = 5)
        public ResponseEntity hello(String name) {
            System.out.println("................");
            return buildResponseEntity("word","hello " + name);
        }
    
        @RequestMapping({ "/Permission" })
        public ResponseEntity Permission(String name) {
            return buildResponseEntity("word","Permission " + name);
        }
    }
    

    限制1秒钟 只能 有五个请求才能走方法

    验证
    image.png
    注意:@ApiRateLimiter(value = ) 根据业务需要设定相应的值

    相关文章

      网友评论

          本文标题:AOP+ RateLimiter单机限流

          本文链接:https://www.haomeiwen.com/subject/lzfztktx.html