zoukankan      html  css  js  c++  java
  • 如何限制一个接口被调用多次?-限流实战

    引入依赖

    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>
    

    限流实现

    package com.sb.rateLimiter.service;
     
    import com.google.common.util.concurrent.RateLimiter;
    import org.springframework.stereotype.Service;
     
    @Service
    public class RateLimiterService {
        /**
         * 每秒只发出5个令牌
         */
        RateLimiter rateLimiter = RateLimiter.create(5.0);
     
        /**
         * 尝试获取令牌
         * @return
         */
        public boolean tryAcquire(){
            return rateLimiter.tryAcquire();
        }
    }
    

    自定义拦截器,在拦截器中实现限流

    package com.sb.rateLimiter.interceptor;
    import com.sb.rateLimiter.annotation.RateLimiterAnnotation;
    import com.sb.rateLimiter.service.RateLimiterService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    @Component
    public class RateLimiterInterceptor implements HandlerInterceptor {
        @Resource
        private RateLimiterService accessLimitService;
     
        private Logger logger = LoggerFactory.getLogger(RateLimiterInterceptor.class);
     
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if (!(handler instanceof HandlerMethod)) {
                return true;
            }
     
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            RateLimiterAnnotation rateLimiterAnnotation = handlerMethod.getMethod().getAnnotation(RateLimiterAnnotation.class);
            if(rateLimiterAnnotation == null) {
                return true;
            }
     
            if (!accessLimitService.tryAcquire()) {
                logger.info("限流中......");
                return false;
            }
            logger.info("请求成功");
            return true;
        }
     
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
     
        }
     
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
     
        }
    }
    

    实现 WebMvcConfigurer 添加自定义拦截器

    package com.sb.rateLimiter.config;
    import com.sb.rateLimiter.interceptor.RateLimiterInterceptor;
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import javax.annotation.Resource;
     
    @SpringBootConfiguration
    public class WebConfiguration implements WebMvcConfigurer {
     
        @Resource
        private RateLimiterInterceptor rateLimiterInterceptor;
     
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(rateLimiterInterceptor).addPathPatterns("/**");
        }
    }
    
    

    自定义限流注解RateLimiterAnnotation

    
    package com.sb.rateLimiter.annotation;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
     
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface RateLimiterAnnotation {
        int rateLimiterNumber() default 1;
    }
    

    demo测试

    
    package com.sb.rateLimiter.controller;
    import com.sb.rateLimiter.annotation.RateLimiterAnnotation;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
     
    @RestController
    @RequestMapping("/api")
    public class RateLimiterController {
     
        @RateLimiterAnnotation
        @RequestMapping(value = "/rateLimiterTest", method = RequestMethod.GET)
        public void rateLimiterTest() throws Exception {
            //业务逻辑;
        }
    

    通过jmeter进行限流测试

  • 相关阅读:
    iOS开发之窗口和视图
    GCD
    禁止非法用户登录综合设置
    大数减法(C++实现)
    大数加法(C++实现)
    迷宫问题 (BFS ➕输出路径)
    Pots (BFS ➕ 输出路径)
    Shuffle'm Up (map ➕ BFS)
    Prime Path (BFS)
    速算24点
  • 原文地址:https://www.cnblogs.com/fangh816/p/13305254.html
Copyright © 2011-2022 走看看