• 封装RateLimiter 令牌桶算法


    自定义注解封装RateLimiter.实例:

    @RequestMapping("/myOrder")

    @ExtRateLimiter(value = 10.0, timeOut = 500)

    public String myOrder() throws InterruptedException {

               System.out.println("myOrder");

               return "SUCCESS";

    }

    自定义注解

    @Target(value = ElementType.METHOD)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface ExtRateLimiter {

          double value();

     

          long timeOut();

    }

    编写AOP

    @Aspect

    @Component

    public class RateLimiterAop {

          // 存放接口是否已经存在

          private static ConcurrentHashMap<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<String, RateLimiter>();

     

          @Pointcut("execution(public * com.it.api.*.*(..))")

          public void rlAop() {

          }

     

          @Around("rlAop()")

          public Object doBefore(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

               MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();

               // 使用Java反射技术获取方法上是否有@ExtRateLimiter注解类

               ExtRateLimiter extRateLimiter = signature.getMethod().getDeclaredAnnotation(ExtRateLimiter.class);

               if (extRateLimiter == null) {

                     // 正常执行方法

                     Object proceed = proceedingJoinPoint.proceed();

                     return proceed;

               }

               // ############获取注解上的参数 配置固定速率 ###############

               // 获取配置的速率

               double value = extRateLimiter.value();

               // 获取等待令牌等待时间

               long timeOut = extRateLimiter.timeOut();

               RateLimiter rateLimiter = getRateLimiter(value, timeOut);

               // 判断令牌桶获取token 是否超时

               boolean tryAcquire = rateLimiter.tryAcquire(timeOut, TimeUnit.MILLISECONDS);

               if (!tryAcquire) {

                     serviceDowng();

                     return null;

               }

               // 获取到令牌,直接执行..

               Object proceed = proceedingJoinPoint.proceed();

               return proceed;

     

          }

     

          // 获取RateLimiter对象

          private RateLimiter getRateLimiter(double value, long timeOut) {

               // 获取当前URL

               ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

               HttpServletRequest request = attributes.getRequest();

               String requestURI = request.getRequestURI();

               RateLimiter rateLimiter = null;

               if (!rateLimiterMap.containsKey(requestURI)) {

                     // 开启令牌通限流

                     rateLimiter = RateLimiter.create(value); // 独立线程

                     rateLimiterMap.put(requestURI, rateLimiter);

               } else {

                     rateLimiter = rateLimiterMap.get(requestURI);

               }

               return rateLimiter;

          }

     

          // 服务降级

          private void serviceDowng() throws IOException {

               // 执行服务降级处理

               System.out.println("执行降级方法,亲,服务器忙!请稍后重试!");

               ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

               HttpServletResponse response = attributes.getResponse();

               response.setHeader("Content-type", "text/html;charset=UTF-8");

               PrintWriter writer = response.getWriter();

               try {

                     writer.println("执行降级方法,亲,服务器忙!请稍后重试!");

               } catch (Exception e) {

     

               } finally {

                     writer.close();

               }

     

          }

     

          public static void main(String[] args) {

               // 使用Java反射技术获取方法上是否有@ExtRateLimiter注解类

               ExtRateLimiter extRateLimiter = IndexController.class.getClass().getAnnotation(ExtRateLimiter.class);

               System.out.println(extRateLimiter);

          }

     

    }

    运行效果

    @RequestMapping("/myOrder")

    @ExtRateLimiter(value = 10.0, timeOut = 500)

    public String myOrder() throws InterruptedException {

               System.out.println("myOrder");

               return "SUCCESS";

    }

  • 相关阅读:
    华为云招募工业智能领域合作伙伴,强力扶持+商业变现
    “不敢去怀疑代码,又不得不怀疑代码”记一次网络请求超时分析
    详解openGauss多线程架构启动过程
    站在数字化风口,工装企业如何“飞起来”
    如何化解35岁危机?华为云数据库首席架构师20年技术经验分享
    解读2022年度敏捷教练行业现状报告
    理论+案例,带你掌握Angular依赖注入模式的应用
    机器学习实践:基于支持向量机算法对鸢尾花进行分类
    8种桌面IDE CodeArts智能代码补全类型
    【CVPR2022】用于域适应语义分割的域无关先验
  • 原文地址:https://www.cnblogs.com/a1304908180/p/10721474.html
Copyright © 2020-2023  润新知