前 言

Nginx

限 流

限流

如 图:

图片

自己魔改出来的漫画

如图上的漫画,在某个时间段流量上来了,服务的接口访问频率可能会非常快,如果我们没有对接口访问频次做限制可能会导致服务器无法承受过高的压力挂掉,这时候也可能会产生数据丢失,所以就要对其进行限流处理。

限流算法就可以帮助我们去控制每个接口或程序的函数被调用频率,它有点儿像保险丝,防止系统因为超过访问频率或并发量而引起瘫痪。我们可能在调用某些第三方的接口的时候会看到类似这样的响应头:

HTTP Response

一般来说,限流的常用处理手段有:

  • 计数器
  • 滑动窗口
  • 漏桶
  • 令牌桶

计数器

在一段时间间隔内,对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清零。
count+1count11countcount

代码实现:

OutPut:

2021/02/01 21:16:12 创建请求: 0
2021/02/01 21:16:12 响应请求: 0
2021/02/01 21:16:12 创建请求: 1
2021/02/01 21:16:12 响应请求: 1
2021/02/01 21:16:12 创建请求: 2
2021/02/01 21:16:13 创建请求: 3
2021/02/01 21:16:13 创建请求: 4
2021/02/01 21:16:13 创建请求: 5
2021/02/01 21:16:13 响应请求: 5
2021/02/01 21:16:13 创建请求: 6
2021/02/01 21:16:13 响应请求: 6
2021/02/01 21:16:13 创建请求: 7
2021/02/01 21:16:13 响应请求: 7
2021/02/01 21:16:14 创建请求: 8
2021/02/01 21:16:14 创建请求: 9

200ms132、3、4、8、9
/queryCounter

如下图:

这种方法虽然简单,但也有个大问题就是没有很好的处理单位时间的边界。

滑动窗口

滑动窗口滑动窗口(Sliding window)TCP滑动窗口

如 图:

图片

一分钟61010Counter0:45+10:40~0:50

那么滑动窗口如何解决我们上面遇到的问题呢?来看下面的图:

图片

0:59200+200200
格子的数量影响着滑动窗口算法的精度,依然有时间片的概念,无法根本解决临界点问题

漏 桶

漏桶算法(Leaky Bucket)

如 图:

图片

处理速度流量整形流量控制

代码实现:

漏桶算法有以下特点:

  • 漏桶具有固定容量,出水速率是固定常量(流出请求)
  • 如果桶是空的,则不需流出水滴
  • 可以以任意速率流入水滴到漏桶(流入请求)
  • 如果流入水滴超出了桶的容量,则流入的水滴溢出(新请求被拒绝)

漏桶限制的是常量流出速率(即流出速率是一个固定常量值),所以最大的速率就是出水的速率,不能出现突发流量。

令牌桶算法

(Token Bucket)(Traffic Shaping)(Rate Limiting)

图片

(token)(rate)

实现代码:

令牌桶有以下特点:

BN

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

小 结

令牌桶