美文网首页
服务治理 - 限流

服务治理 - 限流

作者: 赤子心_d709 | 来源:发表于2019-03-21 21:36 被阅读0次

    背景

    有些场景并不能用缓存和降级来解决,比如稀缺资源(秒杀、抢购)、写服务(如评论、下单)、频繁的复杂查询(评论的最后几页),因此需有一种手段来限制这些场景的并发/请求量,即限流。

    限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或默认数据,如商品详情页库存默认有货)。

    一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如nginx的limit_conn模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如Guava的RateLimiter、nginx的limit_req模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制MQ的消费速率。另外还可以根据网络连接数、网络流量、CPU或内存负载等来限流。

    限制总并发数

    限制总并发数用到的连接池之前有源码分析,commons-pool2(考虑到连接池复用,状态维护的产物)

    如果仅仅是维护一个int值的话,甚至一个atomic值就可以,维护maxConnection,maxThread这种即可

    限制瞬时流量

    这里从服务调用层面开始讲

    常见算法

    计数器

    简单暴力算法,比如限制每分钟QPS10000
    那么做一个map <分钟时间,请求总量>
    维护这个map即可

    缺陷:可能1分钟里面前面都没有qps,最后1s有1w的qps,不好处理这种流量不均的情况

    时间窗口

    滑动窗口比较经典的应用是在TCP上,TCP的拥塞控制就是滑动窗口协议价上一系列的控制算法完成的。我们将滑动窗口应用在流量控制上可以有以下算法。


    1s分成10个窗口,每100ms滑动一个窗口

    滑动时间窗口在计数器的思想上做了一些微分,将流量归入不同的窗口,在上一节熔断器就是讲解的就是这种方法,窗口越小,滑动到下一个窗口波动越小

    队列法

    以流量次数为基准,去统计时间间隔。
    例如,我们限制一分钟请求次数是10,我们将每次访问的时间存入队列。然后计算最近一次和第十次的时间间隔是否超过1分钟。

    漏桶法

    漏桶法

    注意

    一个固定容量的漏桶,按照常量固定速率流出水滴;
    如果桶是空的,则不需流出水滴;
    可以以任意速率流入水滴到漏桶;
    如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的。
    

    令牌桶

    令牌桶
    以一个恒定的速率向固定容量大小桶中放入令牌,当有流量来时则取走一个或多个令牌。当桶中没有令牌则将当前请求丢弃或阻塞

    应用

    瞬时限流

    go https://github.com/juju/ratelimit
    guava RateLimiter

    限制总量

    mysql,redis等

    思考

    为什么上一节熔断要时间窗口,这一节限流可以有队列法

    我理解熔断中一个窗口要维护几个值,成功,失败,超时,是一个结构体,
    但是限流里面一个窗口就一个值,已执行请求数,就没必要再维护窗口,可以有其他简单方法解决

    为什么上一节熔断不能漏桶,令牌桶

    桶适配“流量控制”这个场景,和熔断没什么关系

    漏桶和令牌桶区别

    漏桶定量放出,流入请求速率任意,当流入的请求数累积到漏桶容量时,则新流入的请求被拒绝,不允许突发请求
    令牌桶定量流入,允许突发请求,只要有令牌就可以处理

    令牌桶算法思想与漏桶相似,不过是反过来的,漏桶算定时消费,令牌桶算定时生产

    分布式场景的应用

    上面比如令牌桶可以单机实现,也可以分布式实现,如果分布式,就相当于需要分布式锁以及分布式计数器来完成

    相关文章

      网友评论

          本文标题:服务治理 - 限流

          本文链接:https://www.haomeiwen.com/subject/nqlhvqtx.html