简单学习限流
目的:
通过对并发访问和请求进行限速或者一个时间窗口内的请求进行限速来保护系统的可用性,一旦达到限制速率就可以拒绝服务(友好定向到错误页或告知资源没有了),排队或者等待(比如秒杀,评论,下单),降级(返回默认数据)。
通过压测的手段找到每个系统的处理峰值,然后通过设定峰值阈值,来防止当系统过载时,通过拒绝处理过载的请求来保障系统 可用性,同时也应该根据系统的吞吐量,响应时间,可用率来动态调整限流阈值。
分类:
- 限制总并发数---数据库连接池,线程池
- 限制瞬时并发数---nginx的limit_conn模块,用来限制瞬时并发连接数
- 限制时间窗口内的平均速率---guava的RateLimiter,nginx的limit_req模块,限制每秒平均速率
- 其他---限制远程接口调用速率,限制MQ消费速率,另外,还可以根据网络连接数,网络流量,CPU或内存负载等来限流。
算法:
- 滑动窗口协议---改善吞吐量的技术
- 漏桶---强制限制数据的传输速率,限制的流出速率
- 令牌桶---(控制(流入)速率类型的限流算法)系统以恒定的速度往桶中放入令牌,如果请求需要被处理,则需要先从桶中获取一个令牌,当桶中没有令牌可取,则拒绝服务。当平时处理速率小于桶中令牌的速率,那么在突发流量时桶内有堆积可以有效预防。
令牌桶和漏桶的对比:
- 令牌桶是按照固定的速率往桶中添加令牌,请求是否被处理需要看桶中令牌是否足够,当令牌数为0,则拒绝新的请求
- 漏桶则是按照常量固定速率流出请求,流入请求速率任意,当流入请求数累计到漏桶容量时,则新的请求被拒绝。
- 令牌桶限制的是平均流入速率(允许突发请求,只要有令牌就可以处理,一次拿3个令牌,4个令牌),并允许一定程度并发流量
- 漏桶限制的是常量流出速率(即流出速率是一个固定常量值,比如都是1的速率流出,而不能一次是1,下次是2),从而平滑的解决了突发流入速率
- 两个算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。
- 计数器(***)---通过控制时间段内的请求次数,限制总并发数,比如数据库连接池大小,线程池大小,秒杀并发数都是计数器的用法。只要全局总请求数或者一段时间内的请求数达到设定阈值,则进行限流。对比上面的速率限流,该算法是总数量限流。
策略:
- Nginx接入层限流
- 对某个key对应的总的网络连接数进行限流,可以按照一定的规则如账号,IP,系统调用逻辑等在Nginx层面做限流---连接数限流模块:limit_conn
- 对某个key对应的请求的平均速率进行限流,两种:平滑模式和允许突发模式---请求限流模块:limit_req
- 应用级限流
- 限流总并发/连接/请求数---设定合适的阈值(tomcat,redis,mysql等都有类似配置)
- 限流总资源数---数据库连接池,线程池
- 限流接口的总并发/请求数---适用于可降级的业务场景,可以让用户友好接受。可以使用计数器方式实现。
- 限流接口的时间窗口请求数---使用计数器方式
- 平滑限流接口请求数(应对突发流量)---令牌桶/漏桶
《亿级流量网站架构核心技术》