zoukankan      html  css  js  c++  java
  • TPS限流

    限流是高可用服务需要具备的能力之一 ,粗暴简单的就像我们之前做的并发数控制。好一点的有tps限流,可用令牌桶等算法实现。《亿级流量网站架构核心技术》一书P67限流详解也有讲。dubbo提供了此机制,TpsLimitFilter。guava也提供了相应的工具类RateLimiter。

    1. dubbo提供的tps限流

    1.1 demo使用

    1.1.1 在source folder下放置,META-INF/dubbo/com.alibaba.dubbo.rpc.Filter

    里面写入 tpslimiter=com.alibaba.dubbo.rpc.filter.TpsLimitFilter
    表示将TpsLimitFilter这个filter的扩展给装配给dubbo

    1.1.2 provider侧的配置

    <dubbo:service interface="org.simonme.dubbo.demo.provider.service.HelloService" ref="m00001.app001.xx.helloService" filter="tpslimiter">
        <dubbo:parameter key="tps" value="5" />
    </dubbo:service>
    

    意思对HelloService 这个接口在provider侧做tps为5的限流,默认间隔是60s,可以通过tps.interval这个parameter进行配置,单位是毫秒。注意此处配置的tps为5,不是每秒限制通过5个以内的请求,而是单位时间间隔内通过5个以内的请求。关于单位时间间隔前面解释了。

    1.2 如果超限了是什么现象?

    客户端会抛出rpc调用异常:
    com.alibaba.dubbo.rpc.RpcException: Failed to invoke service org.simonme.dubbo.demo.provider.service.HelloService.sayHello because exceed max service tps

    1.3 原理分析

    主要是DefaultTPSLimiterStatItem两个类配合完成。采用的是令牌桶算法,实现在StatItem类中。
    大意是:
    每隔一个单位时间后重置令牌桶中令牌的数量,然后每次请求来的时候减1,减到小于0时,拒绝请求。

    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();
    }
    

    注意:此实现依赖系统时间,如果想用相对时间实现,可以参见这里 dubbo的TPS限流模块在运行时系统时间发生变化的情况下限流不能正常工作 #2345

    2. spring cloud

    对于采用spring cloud的架构的项目,可以借助guava的RateLimiter来实现ZuulFilter的子类来达成tps限流的目的。

  • 相关阅读:
    js常用框架原理
    移动端input解决键盘问题 方案1
    jq大体架构。先记录再慢慢剖析
    把图片存储 canvas原生API转成base64
    清除浮动的6中方法
    window.location.hash属性介绍
    前端性能优化之js,css调用优化
    数组中的对象,判断是否有重复值、
    [Python] Pitfalls: Be Careful with os.chdir
    Changing the Color of Linux ls Command 改变Linux的ls命令显示的颜色
  • 原文地址:https://www.cnblogs.com/simoncook/p/9567604.html
Copyright © 2011-2022 走看看