利用RateLimiter实现通用限流器注解

1.最终效果

例如:@AccessFast(qps = 10),在注解中配置qps参数,每秒最多10次request请求.即可实现限流效果

    @AccessFast(qps = 10)
    @ApiOperation(value = "根据id查询详情")
    @RequestMapping(value = "/info/{id}", method = RequestMethod.POST)
    public R info1(@PathVariable(value = "id") Long id) {
        return kidGrowReportService.getKidGrowReportById(id);
    }

2.具体代码

(1)注解类 AccessFast
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessFast {
   int qps() default -1;//每秒限制最多多少个请求 qps=-1表示不限流-目前的限流器针对具体uri
   int timeout() default -1;//超时限制,单位为毫秒---如果有超时限制,则一定为非阻塞,block参数无需考虑
   boolean block() default true;//是否阻塞
}
(2)拦截器
    //限流器容器
    private Map rateMaps = Maps.newConcurrentMap();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (null != handler) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            if (null != method) {
                // 获取限流注解
                AccessFast methodAnnotation = method.getAnnotation(AccessFast.class);
                if (methodAnnotation != null) {
                    int qps = methodAnnotation.qps();
                    int timeout = methodAnnotation.timeout();
                    boolean block = methodAnnotation.block();

                    if (qps != -1) {//限流
                        String requestURI = request.getRequestURI();
                        RateLimiter rateLimiter = rateMaps.get(requestURI);
                        if (rateLimiter == null) {
                            rateLimiter = RateLimiter.create(qps);
                            rateMaps.put(requestURI, rateLimiter);
                            return true;
                        }

                        if (timeout != -1) {//非阻塞
                            logger.info("AccessFast | not block");
                            if (rateLimiter.tryAcquire(timeout, TimeUnit.MILLISECONDS)) {
                                logger.info("AccessFast | success");
                                return true;
                            } else {
                                logger.info("AccessFast | not block timeout:{}", timeout);
                                return false;
                            }
                        } else {
                            if (block){//阻塞
                                double acquire = rateLimiter.acquire();
                                logger.info("AccessFast | block time:{} | acquire", acquire);
                            }else {
                                if(rateLimiter.tryAcquire()){
                                    logger.info("AccessFast | not block | tryAcquire");
                                }
                            }
                        }
                    }
                    return true;
                }
            }
        }
        
    }

你可能感兴趣的:(利用RateLimiter实现通用限流器注解)