共计 1466 个字符,预计需要花费 4 分钟才能阅读完成。
一、限流是高可用的利器之一
众所皆知,限流是通过对某段时间(如双 11)的大流量申请进行限速,以此达到爱护零碎的目标。大促之前,咱们能够通过压测等伎俩测出零碎以后最大接受的解决阈值,即峰值 QPS/TPS,一旦流量达到峰值,咱们能够施行降级,比方让用户排队期待,稍后再试。上面就来具体聊聊限流的罕用算法和施行策略。
二、限流算法
常见的限流算法有令牌桶,漏桶。计数器、信号量也能够用来做简略的限流。
1. 令牌桶算法
令牌桶算法的根本过程如下(摘自百度百科):
1. 如果用户配置的均匀发送速率为 r,则每隔 1 / r 秒一个令牌被退出到桶中;
2. 假如桶最多能够存发 b 个令牌。如果令牌达到时令牌桶曾经满了,那么这个令牌会被抛弃;
3. 当一个 n 个字节的数据包达到时,就从令牌桶中删除 n 个令牌,并且数据包被发送到网络;
4. 如果令牌桶中少于 n 个令牌,那么不会删除令牌,并且认为这个数据包在流量限度之外;
5. 算法容许最长 b 个字节的突发,但从长期运行后果看,数据包的速率被限度成常量 r。对于在流量限度外的数据包能够以不同的形式解决:
它们能够被抛弃;
它们能够排放在队列中以便当令牌桶中累积了足够多的令牌时再传输;
它们能够持续发送,但须要做非凡标记,网络过载的时候将这些非凡标记的包抛弃。
2. 漏通算法
漏桶算法的根本过程如下(摘自百度百科):
1、队列接管到筹备转发的数据包。
2、队列被调度,失去转发机会。因为队列配置了流量整形,队列中的数据包首先进入漏桶中。
3、依据数据包达到漏桶的速率与漏桶的输入速率关系,确定数据包是否被转发。漏桶的输入速率是恒定的。
如果达到速率≤输入速率,则漏桶不起作用。
如果达到速率 > 输入速率,则需思考漏桶是否能承当这个霎时的流量。
1)若数据包达到的速率 - 漏桶流出的速率≤配置的漏桶突发速率,则数据包可被不延时的送出。
2)若数据包达到的速率 - 漏桶流出的速率 > 配置的漏桶突发速率,则多余的数据包被存储到漏桶中。暂存在漏桶中的数据包在不超过漏桶容量的状况下延时收回。
3)若数据包达到的速率 - 漏桶流出的速率 > 配置的漏桶突发速率,且数据包的数量曾经超过漏桶的容量,则这些数据包将被抛弃。
3. 令牌桶算法和漏桶算法的区别
漏桶算法与令牌桶算法在外表看起来相似,很容易将两者混同。但事实上,这两者具备截然不同的个性,且为不同的目标而应用。漏桶算法与令牌桶算法的区别在于:
1. 漏桶算法可能强行限度数据的传输速率。
2. 令牌桶算法可能在限度数据的均匀传输速率的同时还容许某种程度的突发传输。
须要阐明的是:在某些状况下,漏桶算法不可能无效地应用网络资源。因为漏桶的漏出速率是固定的,所以即便网络中没有产生拥塞,漏桶算法也不能使某一个独自的数据流达到端口速率。因而,漏桶算法对于存在突发个性的流量来说不足效率。而令牌桶算法则可能满足这些具备突发个性的流量。通常,漏桶算法与令牌桶算法联合起来为网络流量提供更高效的管制。
三、利用级限流
1. 限流零碎总并发 / 连贯 / 申请数
峰值 QPS/TPS
2. 限度总资源数
数据库连接池,线程池等
3. 限度某个接口的总并发 / 申请数
秒杀抢购业务接口
4. 限度某个接口的工夫窗申请数
限度每秒 / 每分钟 / 每天调用接口的申请数
平滑限流某个接口的申请数
流量速率整形,突发流量整形为平均速度流量,常见的有 Guava 的 RateLimter 令牌桶算法实现。
四、分布式限流
实现计划:Redis+Lua
Redis 放计数器,Lua 写原子化的脚本
五、接入层限流
nginx 的 limit_conn 模块和 limit_req 模块,对连接数和申请数进行限度。
参考资料:
《亿级流量网站架构核心技术》