@Aspect
@Component
public class RateLimiterAop {// 创建map,key是URL,value是令牌,同一个请求就覆盖上一个值private static ConcurrentHashMap<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<String, RateLimiter>();//切入点,拦截com.lzh.demo包下的所有的public类和方法@Pointcut("execution(public * com.lzh.demo.*(..))")public void rlAop() {} //使用AOP环绕通知判断拦截所有springmvc的请求,判断请求方法上是否存在ExtRateLimiter @Around("rlAop()")public Object doBefore(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//判断是否存在@ExtRateLimiter注解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对象,保证每个请求都是单例的,比如很多的同一个pay请求可以共用一个ratelimiter,   //但是如果是order请求,那么就必须再创建一个ratelimiter,根据URL进行判断private RateLimiter getRateLimiter(double value, long timeOut) {// 获取当前URIServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String requestURI = request.getRequestURI();RateLimiter rateLimiter = null;if (!rateLimiterMap.containsKey(requestURI)) {// 如果没有检测到URI,那么创建一个新的ratelimiterrateLimiter = RateLimiter.create(value); // 独立线程
            rateLimiterMap.put(requestURI, rateLimiter);} else {// 能够在map中检测到URL就添加到map中,相同的请求在同一个ratemiliter中rateLimiter = rateLimiterMap.get(requestURI);}return rateLimiter;}// 服务降级private void serviceDowng() throws IOException {     // 获取响应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();}}
}

@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtRateLimiter {  // 以秒为单位的速率往桶中存令牌double value();// 规定的毫秒内如果没有得到令牌那么就走降级服务long timeOut();
}

package com.lzh.demo

// 测试代码@RequestMapping("/myOrder")
@ExtRateLimiter(value = 10.0, timeOut = 500)
public String myOrder() throws InterruptedException {System.out.println("myOrder");return "SUCCESS";
}

转载于:https://www.cnblogs.com/lzh110/p/9555374.html

令牌桶的自定义注解核心API演示相关推荐

  1. Java反射自定义注解底层设计原理

    文章目录 一.反射 1. 反射概念 2. 反射机制的优缺点 3. 反射的用途 4. 反射技术的使用 5. 反射常用的Api 6. 反射执行构造函数 7. 反射执行给属性赋值 8. 反射执行调用方法 二 ...

  2. 漏斗算法和令牌桶算法

    目录 干什么用的? 什么是漏斗算法 令牌桶算法 令牌锁的使用 干什么用的? 这两个算法来源于计算机网络.在网络传输数据时,为了防止网络拥塞,需要限制网络中的流量,即限流 什么是漏斗算法 水(大量并发的 ...

  3. Android 自定义注解详细用法,手写Butterknife黄油刀

    前言 本篇文章主要讲解 Java 注解在Android中的常见用法 Java 注解(Annotation) Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释 ...

  4. 【229期】Spring Boot 使用令牌桶算法+拦截器+自定义注解+自定义异常实现简单的限流...

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...

  5. AOP+自定义注解token令牌和参数防重复提交实战

    目录 一.哪些因素会引起重复提交? 二.重复提交会带来哪些问题? 三.订单的防重复提交你能想到几种方案? 四.自定义注解方式 4.1Java核心知识-自定义注解(先了解下什么是自定义注解) 4.1.1 ...

  6. Web API 速率限制(二)- 令牌桶算法简介

    前情提要 上一篇文章里简单介绍了什么是Web API的速率限制,和限速策略需考虑的问题,最后还介绍了ASP.NET Core 的一个常用限速库.......的名字. 实施策略 如果你想要建立一个限速系 ...

  7. 可能要用心学高并发核心编程,限流原理与实战,分布式令牌桶限流

    实战:分布式令牌桶限流 本节介绍的分布式令牌桶限流通过Lua+Java结合完成,首先在Lua脚本中完成限流的计算,然后在Java代码中进行组织和调用. 分布式令牌桶限流Lua脚本 分布式令牌桶限流Lu ...

  8. 用令牌桶算法完成API接口限流

    这是张富涛的第15篇原创 用令牌桶算法完成API接口限流 本文介绍了"令牌桶算法",和使用lua+redis实现基于令牌桶算法的限流. 1. 限流需求的产生背景 软件开发时偶尔会面 ...

  9. Java 自定义注解简单使用

    Java 自定义注解简单使用 文章目录 Java 自定义注解简单使用 第一步:在 pom.xml 下引入反射框架 第二步:自定义注解 第三步:写两个测试实体类 第四步:写个工具类扫描被注解的类(核心) ...

最新文章

  1. sklearn FutureWarning: numpy not_equal will not check..., The comparison did not return the same
  2. 在html利用canvas蚂蚁,html5 利用canvas实现简单的人物走动
  3. Oracle单机版开机自启动
  4. 解决CentOS6.5虚拟机克隆后无法上网(网卡信息不一致)的问题
  5. react useRef()函数
  6. what is your research about?
  7. 20万人仍然每天活跃在“死”掉的ofo APP上:这已变成一个返利应用
  8. .NET 现代化动态 LINQ 库 Gridify
  9. php 删除数组的空元素,php删除数组空元素的方法_后端开发
  10. 记一次 Redis Cluster 宕机引发的事故
  11. matlab 散点 面,求大神指点绘制空间内散点图的包络面,,,散点程序如下
  12. linux文件夹压缩与分卷压缩
  13. Unity Spine 换装
  14. shiro权限框架中五张基本数据表
  15. Java API版权第一大案,索赔百亿美元,打了10年终于有结果了!
  16. IntelliJ IDEA汉化,IntelliJ IDEA安装中文语言包。IntelliJ IDEA 2020.1正式发布,支持中文啦。
  17. dwz交互式弹窗处理
  18. kafka的副本以及分区与副本的关系
  19. linux增加分辨率addmode,设置分辨率xrandr --addmode
  20. 关于java转义字符\解析。

热门文章

  1. python画三维立体图-Python+matplotlib绘制三维图形5个精选案例
  2. python培训好学吗-人工智能“速成班”Python好学吗 小心别被忽悠了
  3. 解决安装下载好的whl库包时,报错:zipfile.BadZipFile: File is not a zip file
  4. 8_用opencv调用深度学习框架tenorflow、Pytorch、Torch、caffe训练好的模型(20190212)
  5. UVa10905 - Children's Game(贪心算法)
  6. WAT中Security选项卡无法连接到数据库解决办法
  7. 调试兼容性该注意的的点
  8. keras 模型简介
  9. Quartz学习笔记
  10. Bitcoin Core P2P网络层