博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dubbo 限流之TpsLimitFilter
阅读量:4679 次
发布时间:2019-06-09

本文共 2651 字,大约阅读时间需要 8 分钟。

常见的限流方式有:计数器、滑动窗口、漏斗和令牌桶算法

计数器 VS 滑动窗口

计数器算法是最简单的算法,可以看成是滑动窗口的低精度实现。滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。

漏桶算法 VS 令牌桶算法

漏桶算法和令牌桶算法最明显的区别是令牌桶算法允许流量一定程度的突发。因为默认的令牌桶算法,取走token是不需要耗费时间的,也就是说,假设桶内有100个token时,那么可以瞬间允许100个请求通过。

令牌桶算法由于实现简单,且允许某些流量的突发,对用户友好,所以被业界采用地较多。当然我们需要具体情况具体分析,只有最合适的算法,没有最优的算法。

dubbo 默认实现的是滑动窗口的方式。

@Activate(group = Constants.PROVIDER, value = Constants.TPS_LIMIT_RATE_KEY)public class TpsLimitFilter implements Filter {    private final TPSLimiter tpsLimiter = new DefaultTPSLimiter();    @Override    public Result invoke(Invoker
invoker, Invocation invocation) throws RpcException { if (!tpsLimiter.isAllowable(invoker.getUrl(), invocation)) { throw new RpcException( "Failed to invoke service " + invoker.getInterface().getName() + "." + invocation.getMethodName() + " because exceed max service tps."); } return invoker.invoke(invocation); }}
public class DefaultTPSLimiter implements TPSLimiter {  // 存储每个服务的key和每个服务限制的请求数。    private final ConcurrentMap
stats = new ConcurrentHashMap
(); @Override public boolean isAllowable(URL url, Invocation invocation) { int rate = url.getParameter(Constants.TPS_LIMIT_RATE_KEY, -1); // 窗口内的最大请求数 long interval = url.getParameter(Constants.TPS_LIMIT_INTERVAL_KEY, Constants.DEFAULT_TPS_LIMIT_INTERVAL); // 窗口大小 String serviceKey = url.getServiceKey(); // 服务唯一key if (rate > 0) { StatItem statItem = stats.get(serviceKey); if (statItem == null) { stats.putIfAbsent(serviceKey, new StatItem(serviceKey, rate, interval)); statItem = stats.get(serviceKey); } return statItem.isAllowable(); } else { StatItem statItem = stats.get(serviceKey); if (statItem != null) { stats.remove(serviceKey); } } return true; }}
public boolean isAllowable() {        long now = System.currentTimeMillis();        if (now > lastResetTime + interval) { // 重置窗口            token.set(rate);             lastResetTime = now;        }        int value = token.get();        boolean flag = false;        while (value > 0 && !flag) {            flag = token.compareAndSet(value, value - 1); // 每来一个请求减少一个许可            value = token.get();        }        return flag;    }

总结:dubbo 默认的 限流实现比较简单,用户可以自定义限流策略。业界令牌桶用的比较多。

 

转载于:https://www.cnblogs.com/hansc-blog/p/9371990.html

你可能感兴趣的文章
[转]loadrunner:系统的平均并发用户数和并发数峰值如何估算
查看>>
Linux下Tomcat重新启动
查看>>
HTML Table to Json
查看>>
Theano 学习笔记(一)
查看>>
1.7 节点进行排序显示
查看>>
web最佳实践
查看>>
spring 集成shiro 之 自定义过滤器
查看>>
验证密码不允许有连续三位重复的正则表达式
查看>>
python 中对list去重
查看>>
Mono Libgdiplus库
查看>>
js模糊查询案例
查看>>
c语言基础知识要点
查看>>
Android模拟器无法上网访问网络失败解决办法
查看>>
node启动时, listen EADDRINUSE 报错;
查看>>
vue学习链接
查看>>
Systemd 初始化进程
查看>>
【C#学习笔记】文本复制到粘贴板
查看>>
Windows store 验证你的 URL http:// 和 https:// ms-appx:/// ms-appdata:///local
查看>>
python全栈开发_day7_字符编码,以及文件的基本读取
查看>>
js 验证码 倒计时60秒
查看>>