zoukankan      html  css  js  c++  java
  • 自定义限流注解

    了解RateLimiter

    https://blog.csdn.net/qq_38366063/article/details/89070822
    基于这个去实现的自定义限流注解.首先需要了解rateLimiter的简单使用.

    导包只要spring,和guava包即可

    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>27.0.1-jre</version>
    </dependency>
    
    
    

    自定义注解,写切面

    注解MyLimit

    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @ClassName MyLimit
     * @Description MyLimit
     * @Author stack
     * @Version 1.0
     * @since 2019/7/15 16:47
     */
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyLimit {
    
        /**
         * 每秒向桶中放入令牌的数量   
         * 默认最大即不做限流,使用简单的RateLimit,每一秒中放入多少令牌
         * @return
         */
        int permitsPerSecond() default Integer.MAX_VALUE;
    
        /**
         * 获取令牌的等待时间  默认0
         * @return
         */
        int timeOut() default 0;
    
        /**
         * 超时时间单位
         * @return
         */
        TimeUnit unit() default TimeUnit.SECONDS;
    
    }
    

    限流切面:

    
    import com.google.common.util.concurrent.RateLimiter;
    import com.mr.common.ResultCode;
    import com.mr.exception.MyprojectException;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @ClassName MyLimit
     * @Description MyLimit
     * @Author stack
     * @Version 1.0
     * @since 2019/7/15 16:47
     */
    
    @Aspect
    @Component
    @Slf4j
    public class MyLimitAspect {
    
        private static Map<String, RateLimiter> url = new ConcurrentHashMap<>();
    
        @Pointcut("@annotation(com.mr.web.annotation.MyLimit)")
        public void logPointCut() {
        }
    
        @Before("logPointCut()")
        public void doBefore(JoinPoint joinPoint) throws Throwable {
    
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            MyLimit methodAnnotation = method.getAnnotation(MyLimit.class);
    
            double v = methodAnnotation.permitsPerSecond();
            if (v == Integer.MAX_VALUE) {
                return;
            }
    
            if (methodAnnotation != null) {
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String requestURL = request.getRequestURL().toString();
                //根据url判断是否限流。
                if (url.containsKey(requestURL)) {
                    RateLimiter rateLimiter = url.get(requestURL);
                    if (!rateLimiter.tryAcquire(methodAnnotation.timeOut(), methodAnnotation.unit())) {
                        //限流
                        throw new MyprojectException(ResultCode.SYSTEM_ERROR.getError());
                    }
                } else {
                    RateLimiter r = RateLimiter.create(v);
                    url.put(requestURL, r);
                }
            }
        }
    
    }
    
    

    测试

    随便写个测试的controller
    在这里插入图片描述
    在这里插入图片描述

    当请求速度很快在这里插入图片描述

    世界上所有的不公平都是由于当事人能力不足造成的.
  • 相关阅读:
    ARM汇编指令
    Linux系统里如何彻底的清空终端屏幕?
    Linux命令(16)压缩,解压文件
    Linux命令(18)查看当前用户who、whoami、who am i
    Linux命令(17)du 查看文件和目录磁盘使用情况
    Mongodb(3)插入文档,更新文档,删除文档
    Mongodb(2)创建数据库,删除数据库,创建集合,删除集合,显示文档内容
    Mongodb(1)如何存储以及简介
    Linux命令(15)查看系统版本信息
    Python 结巴分词(2)关键字提取
  • 原文地址:https://www.cnblogs.com/javayida/p/13346899.html
Copyright © 2011-2022 走看看