限流该怎么做
限流的核心在于:能“限”在被限制对象的能力上限附近。简单来说就是,设定的阈值要接近被限制对象的能力。一方面,如果阈值过高,限流形同虚设,达不到相应的效果;另一方面,如果阈值过低,频繁触发干预,就会造成误伤。最终都会导致很差的用户体验。因此:
-
首先,要明确限流对象
-
然后,要获得被限制对象的能力上限
-
其次,要制定干预流量的策略
-
最后,就是限流方案的选择与实现
一、确定限流对象
大体上,我们可以从两个方向来确定限流对象:
- 客户端,可以对“每个客户”能够发起的连接数、请求数或请求大小等进行限制。
- 服务端,可以对“每个服务”能够处理的连接数、请求数或请求大小等进行限制。
总的来说,就是要确定是要对客户端的请求能力进行限制,还是要对服务端的处理能力进行限制,又或者是要对两者一起进行限制。
二、获得能力上限
在确定了具体限流对象之后,我们就需要对其能力上限进行评估。
- 对于客户端来说,“每个客户”的请求能力不仅受自身所使用的工具影响,而且受所请求系统的业务场景影响。一般来说,我们可以通过分析系统的请求日志(比如,Nginx的访问日志)得出一个理想的阈值。
- 对于服务端来说,“每个服务”的处理能力不仅受自身特性影响,而且受具体业务场景影响。通常,我们会基于业务场景对系统进行压力测试得出一个理想的阈值。
总的来说,我们可以通过日志分析获得客户端的请求能力,通过压力测试获得服务端的处理能力。
三、制定干预策略
在获得了限流对象的能力上限后,我们就需要采用一定的策略对流量进行干预。常用的策略有4种:”两窗两桶“,具体可参考浅谈限流策略一文。在这里我们主要谈谈对这4种策略的选择:
- 首先,固定窗口。一般来说,如非时间紧迫,不建议选择这个方案。但是,如果为了能快速止损解决眼前问题,可以作为临时应急的方案。
- 其次,滑动窗口。该方案是对固定窗口的改进,适用于对异常结果“高容忍”的场景。相比于“两桶”少了一个缓冲区。但是,实现起来比较简单。
- 然后,漏桶。该方案最适合作为一个通用方案。虽然说在资源的利用率上不是极致的,但是"宽进严出"的思路在保护系统的同时还留有一些余地,使得它的使用场景更广。
- 最后,令牌桶。当我们需要尽可能的压榨系统性能(此时桶的最大容量大于等于系统的最大并发能力),并且所处的场景流量进入波动不是很大(不至于一瞬间取完令牌)时,就可以使用该方案。
四、实现限流方案
完成如上几个步骤之后,一个具体的限流方案基本上也就确定下来了,最后就是实现这个方案了。限流可以做到客户端,也可以做到服务端。那么,我们该如何选择呢?
从效果上看,客户端模式肯定是优于服务端模式的。因为当处于限流状态时,在客户端模式下,建立连接的动作都省去了。另一个潜在的好处是,与集中式的服务端模式相比,可以把服务端的压力分散掉。但是,在客户端做成本很高,因此它是去中心化的,假如需要多个节点之间的数据共通的话,是一个很麻烦的事情。
总的来说,如果考虑成本就服务端模式,考虑效果就客户端模式。当然也不是绝对,比如一个服务端的流量大部分都来源于某一个客户端,那么就可以直接在这个客户端做限流。
五、小结
限流就好比保险丝,根据我们制定的标准,达到了就拉闸。当然,触发限流后的干预措施除了延迟或丢弃请求之外,还可以进行降级。