自定义限流注解

了解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
在这里插入图片描述
在这里插入图片描述

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

世界上所有的不公平都是由于当事人能力不足造成的.
原文地址:https://www.cnblogs.com/javayida/p/13346899.html