限流
大众的限流方案有三种,计数器、漏桶算法、令牌算法
计数器
分为固定窗口和滑动窗口
固定窗口计数器
固定窗口比较简单粗暴,如果假定某个接口1s最多接收100个请求,维护一个固定单位时间的计数器,检测到单位时间过去则重置计数器为0
其不能应对突发的流量,如1s中前100ms处理了99个请求,最后900ms就只能处理一个了
滑动窗口计数器
滑动窗口是对固定窗口的改进
将单位时间分为多个区间,每个区间都有一个计数器,有一个请求落在该区间内,则该区间的计数器就会加一
每过一段时间,时间窗口就会滑动一格,抛弃最老的一个区间,并纳入一个新的区间
计算整个时间窗口内的请求总数时会累加所有时间片段内的计数器
漏桶算法
漏桶算法是利用一个缓存区,当请求进入系统时,无论请求的速率如何,都先在缓存区内保存,然后以固定的流速流出缓存区进行处理,使用队列实现
将每个请求放入固定大小的队列进行存储
队列以固定速率向外流出请求,如果队列为空则停止流出
如果队列满了则多余的请求就被直接拒绝
限制的是流量的流出速率,对于流量均衡的可以使用该方式
无法应对突发的大流量
令牌桶算法
令牌桶算法是一种反向的漏桶算法,桶中存放的不再是请求,而是令牌,只有拿到令牌后,才能对请求进行处理,如果没有令牌,就需要等待可用的令牌,为了限制流速,该算法每单位时间产生一定量的令牌存入桶中
限制的是流量的平均流入速率,可以应对突发流量
Nginx的限流模块就是采用令牌桶算法的实现
每秒有r个令牌放入桶中
桶的容量不变,如果桶满了则不进行存储令牌
如果请求来了,没有令牌会被限流