封装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"; } |
封装RateLimiter 令牌桶算法的更多相关文章
- RateLimiter令牌桶算法
限流,是服务或者应用对自身保护的一种手段,通过限制或者拒绝调用方的流量,来保证自身的负载. 常用的限流算法有两种:漏桶算法和令牌桶算法 漏桶算法 思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度 ...
- coding++:RateLimiter 限流算法之漏桶算法、令牌桶算法--简介
RateLimiter是Guava的concurrent包下的一个用于限制访问频率的类 <dependency> <groupId>com.google.guava</g ...
- 基于令牌桶算法实现的SpringBoot分布式无锁限流插件
本文档不会是最新的,最新的请看Github! 1.简介 基于令牌桶算法和漏桶算法实现的纳秒级分布式无锁限流插件,完美嵌入SpringBoot.SpringCloud应用,支持接口限流.方法限流.系统限 ...
- coding++:Semaphore—RateLimiter-漏桶算法-令牌桶算法
java中对于生产者消费者模型,或者小米手机营销 1分钟卖多少台手机等都存在限流的思想在里面. 关于限流 目前存在两大类,从线程个数(jdk1.5 Semaphore)和RateLimiter速率(g ...
- 15行python代码,帮你理解令牌桶算法
本文转载自: http://www.tuicool.com/articles/aEBNRnU 在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...
- flask结合令牌桶算法实现上传和下载速度限制
限流.限速: 1.针对flask的单个路由进行限流,主要场景是上传文件和下载文件的场景 2.针对整个应用进行限流,方法:利用nginx网关做限流 本文针对第一中情况,利用令牌桶算法实现: 这个方法:h ...
- 令牌桶算法实现API限流
令牌桶算法( Token Bucket )和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS=100 ,则间隔是 10 ...
- 限流10万QPS、跨域、过滤器、令牌桶算法-网关Gateway内容都在这儿
一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...
- php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制
通常在高并发和大流量的情况下,一般限流是必须的.为了保证服务器正常的压力.那我们就聊一下几种限流的算法. 计数器计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理. ...
随机推荐
- jQuery 插件开发——GridData(表格)第二版
开发背景 表格插件之前我也写个一篇,当时写那个插件的时候,我自己还没有总结出写插件的方法,虽然功能实现了,但是使用起来还是有点别扭的,并且需要在调用写添加特定名称的方法,这个地方着实违背了开发插件的易 ...
- [raspberry pi3] 安装aarch64 opensuse
raspberry 虽然是64bit的cpu,但是用的系统一直都是32bit的,32bit的系统还是有不少的局限性的, 比如mongodb,Y2038. suse 发布了个64bit的server版本 ...
- Oauth Client Credentials Grant
http://www.cnblogs.com/dudu/p/4569857.html OAuth真是一个复杂的东东,即使你把OAuth规范倒背如流,在具体实现时也会无从下手.因此,Microsoft. ...
- spring aop实现权限管理
问题源于项目开发 最近项目中需要做一个权限管理模块,按照之前同事的做法是在controller层的每个接口调用之前上做逻辑判断,这样做也没有不妥,但是代码重复率太高,而且是体力劳动,so,便有了如题所 ...
- JavaAppArguments示例
本实验要求编写一个程序,此程序从命令行接收多个数字,求和之后输出结果.一大难点是命令行参数都是字符串,必须先将其转化为数字,才能相加. 中心想法就是将求和数字转换为整型并依次相加. 程序流程图: pu ...
- UC浏览器体验
1.用户界面: 有两个页面,一个展示网页应用-可添加自己喜欢的网页应用,另一个用来搜索,有推荐的常用的网址,有UC头条,页面下有设置,整体布局常规 2.短期刺激: 没有特别花哨的地方:个人感觉比较实用 ...
- VS2015无法创建C++工程解决方法!!
VS2015默认安装时候没有安装C++,如果安装C++没有选择全部C++项目,则无法创建C++工程,在控制面板里的删除程序中,选择VS2015,随后选择修改,把C++项目都选择上就可以了,这样安装完毕 ...
- git rm 与 git reset
https://www.cnblogs.com/sunshine-xin/articles/3521481.html 1. git rm --cached file will remove the f ...
- 洛谷P4137 Rmq Problem / mex(莫队)
题目描述 有一个长度为n的数组{a1,a2,…,an}.m次询问,每次询问一个区间内最小没有出现过的自然数. 输入输出格式 输入格式: 第一行n,m. 第二行为n个数. 从第三行开始,每行一个询问l, ...
- sql_trace基本用法
sql_trace是oracle提供的一个非常好的跟踪工具,主要用来检查数据库的异常情况,通过跟踪数据库的活动,找到有问题的语句. 一.概述: SQL_TRACE是Oracle的一个非常强大的工 ...