zoukankan      html  css  js  c++  java
  • 高并发之限流令牌桶和漏桶算法(一)

    在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流

    • 缓存 缓存的目的是提升系统访问速度和增大系统处理容量
    • 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开
    • 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理

    常用的限流算法

    漏桶算法

    漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

     
    下面时伪代码:
    public class TokenBucketDemo {
        public long timeStamp = getNowTime();
        public int capacity; // 桶的容量
        public int rate; // 水漏出的速度
        public int water; // 当前水量(当前累积请求数)
        public boolean grant() {
            long now = getNowTime();
            water = max(0, water - (now - timeStamp) * rate); // 先执行漏水,计算剩余水量
            timeStamp = now;
            if ((water + 1) < capacity) {
                // 尝试加水,并且水还未满
                water += 1;
                return true;
            }
            else {
                // 水满,拒绝加水
                return false;
            }
        }
    }

    漏桶算法不能够有效地使用网络资源。因为漏桶的漏出速率是固定的参数,所以即使网络中不存在资源冲突(没有发生拥塞),漏桶算法也不能使某一个单独的流突发到端口速率。因此,漏桶算法对于存在突发特性的流量来说缺乏效率。

    令牌桶算法

    对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

     

    令牌桶算法图例

     a. 按特定的速率向令牌桶投放令牌

     b. 根据预设的匹配规则先对报文进行分类,不符合匹配规则的报文不需要经过令牌桶的处理,直接发送;

     c. 符合匹配规则的报文,则需要令牌桶进行处理。当桶中有足够的令牌则报文可以被继续发送下去,同时令牌桶中的令牌 量按报文的长度做相应的减少;

     d. 当令牌桶中的令牌不足时,报文将不能被发送,只有等到桶中生成了新的令牌,报文才可以发送。这就可以限制报文的流量只能是小于等于令牌生成的速度,达到限制流量的目的。

    注意:当令牌不足时,这里报文:

    1、可以被丢弃

    2、可以排放在队列中以便当令牌桶中累积了足够多的令牌时再传输

    3、可以继续发送,但需要做特殊标记,网络过载的时候将这些特殊标记的包丢弃

     伪代码:

    public class TokenBucketDemo {
        public long timeStamp = getNowTime();
        public int capacity; // 桶的容量
        public int rate; // 令牌放入速度
        public int tokens; // 当前令牌数量
        public boolean grant() {
            long now = getNowTime();
            // 先添加令牌
            //min(桶的容量,当前令牌 + 上次请求获取令牌时间到当前时间内生成的令牌)
            tokens = min(capacity, tokens + (now - timeStamp) * rate);
            timeStamp = now;
            if (tokens < 1) {
                // 若不到1个令牌,则拒绝
                return false;
            }
            else {
                // 还有令牌,领取令牌
                tokens -= 1;
                return true;
            }
        }
    }

    令牌桶算法临界问题思考:

    场景:在0:59秒的时候有100个请求过来,此时令牌桶有100个token,瞬间通过。1:00的时候又有100个请求,但令牌放入令牌桶是有一定的速率的,假设rate<100,不可能100个请求都通过。避免了计数器算法瞬间请求过大,压垮系统。

    令牌桶和漏桶对比:

    • 令牌桶是按照固定速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数减为零时则拒绝新的请求;

    • 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝;

    • 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,支持一次拿3个令牌,4个令牌),并允许一定程度突发流量;

    • 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次又是2),从而平滑突发流入速率;

    • 令牌桶允许一定程度的突发,而漏桶主要目的是平滑流入速率;

    • 两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。

    参考:

    https://www.jianshu.com/p/5d4fe4b2a726

    https://www.cnblogs.com/xuwc/p/9123078.html

  • 相关阅读:
    视频安防智能监控系统管理平台EasyNVS切换导航报错Cannot find module ‘@/views/sys/user’问题
    视频安防智能监控系统管理平台EasyNVS手机端扫码直播展示无信号但是PC端可以播放是什么原因?
    RTSP协议视频智能安防监控平台EasyNVR接入大华摄像头无法拉取H265格式视频流如何解决?
    RTSP协议视频智能安防监控平台EasyNVR录像播放及下载接口如何返回在线m3u8格式视频流?
    网页无插件直播视频平台EasyNVR老版本更新版本后CPU占用过高怎么解决?
    【解决方案】如何通过EasyNVR+EasyNVS搭建一套高清智能化的高速公路视频监控管理系统?
    【解决方案】现代化工厂如何实现智能化视频管理?EasyNVR安防视频监控系统打造智慧工厂
    【解决方案】EasyNVR视频边缘计算网关如何实现智慧消防?
    RTSP协议智能安防监控系统EasyNVR硬件设备IP探测软件EasySearcher无法运行如何修复?
    就地过年带旺“云游”,RTSP协议视频监控智能分析平台EasyNVR助力景区“慢直播”
  • 原文地址:https://www.cnblogs.com/xiaozhuanfeng/p/10616987.html
Copyright © 2011-2022 走看看