令牌桶的自定义注解核心API演示
@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演示相关推荐
- Java反射自定义注解底层设计原理
文章目录 一.反射 1. 反射概念 2. 反射机制的优缺点 3. 反射的用途 4. 反射技术的使用 5. 反射常用的Api 6. 反射执行构造函数 7. 反射执行给属性赋值 8. 反射执行调用方法 二 ...
- 漏斗算法和令牌桶算法
目录 干什么用的? 什么是漏斗算法 令牌桶算法 令牌锁的使用 干什么用的? 这两个算法来源于计算机网络.在网络传输数据时,为了防止网络拥塞,需要限制网络中的流量,即限流 什么是漏斗算法 水(大量并发的 ...
- Android 自定义注解详细用法,手写Butterknife黄油刀
前言 本篇文章主要讲解 Java 注解在Android中的常见用法 Java 注解(Annotation) Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释 ...
- 【229期】Spring Boot 使用令牌桶算法+拦截器+自定义注解+自定义异常实现简单的限流...
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...
- AOP+自定义注解token令牌和参数防重复提交实战
目录 一.哪些因素会引起重复提交? 二.重复提交会带来哪些问题? 三.订单的防重复提交你能想到几种方案? 四.自定义注解方式 4.1Java核心知识-自定义注解(先了解下什么是自定义注解) 4.1.1 ...
- Web API 速率限制(二)- 令牌桶算法简介
前情提要 上一篇文章里简单介绍了什么是Web API的速率限制,和限速策略需考虑的问题,最后还介绍了ASP.NET Core 的一个常用限速库.......的名字. 实施策略 如果你想要建立一个限速系 ...
- 可能要用心学高并发核心编程,限流原理与实战,分布式令牌桶限流
实战:分布式令牌桶限流 本节介绍的分布式令牌桶限流通过Lua+Java结合完成,首先在Lua脚本中完成限流的计算,然后在Java代码中进行组织和调用. 分布式令牌桶限流Lua脚本 分布式令牌桶限流Lu ...
- 用令牌桶算法完成API接口限流
这是张富涛的第15篇原创 用令牌桶算法完成API接口限流 本文介绍了"令牌桶算法",和使用lua+redis实现基于令牌桶算法的限流. 1. 限流需求的产生背景 软件开发时偶尔会面 ...
- Java 自定义注解简单使用
Java 自定义注解简单使用 文章目录 Java 自定义注解简单使用 第一步:在 pom.xml 下引入反射框架 第二步:自定义注解 第三步:写两个测试实体类 第四步:写个工具类扫描被注解的类(核心) ...
最新文章
- sklearn FutureWarning: numpy not_equal will not check..., The comparison did not return the same
- 在html利用canvas蚂蚁,html5 利用canvas实现简单的人物走动
- Oracle单机版开机自启动
- 解决CentOS6.5虚拟机克隆后无法上网(网卡信息不一致)的问题
- react useRef()函数
- what is your research about?
- 20万人仍然每天活跃在“死”掉的ofo APP上:这已变成一个返利应用
- .NET 现代化动态 LINQ 库 Gridify
- php 删除数组的空元素,php删除数组空元素的方法_后端开发
- 记一次 Redis Cluster 宕机引发的事故
- matlab 散点 面,求大神指点绘制空间内散点图的包络面,,,散点程序如下
- linux文件夹压缩与分卷压缩
- Unity Spine 换装
- shiro权限框架中五张基本数据表
- Java API版权第一大案,索赔百亿美元,打了10年终于有结果了!
- IntelliJ IDEA汉化,IntelliJ IDEA安装中文语言包。IntelliJ IDEA 2020.1正式发布,支持中文啦。
- dwz交互式弹窗处理
- kafka的副本以及分区与副本的关系
- linux增加分辨率addmode,设置分辨率xrandr --addmode
- 关于java转义字符\解析。
热门文章
- python画三维立体图-Python+matplotlib绘制三维图形5个精选案例
- python培训好学吗-人工智能“速成班”Python好学吗 小心别被忽悠了
- 解决安装下载好的whl库包时,报错:zipfile.BadZipFile: File is not a zip file
- 8_用opencv调用深度学习框架tenorflow、Pytorch、Torch、caffe训练好的模型(20190212)
- UVa10905 - Children's Game(贪心算法)
- WAT中Security选项卡无法连接到数据库解决办法
- 调试兼容性该注意的的点
- keras 模型简介
- Quartz学习笔记
- Bitcoin Core P2P网络层