一、前言
保障服务稳定的三大利器:熔断降级、服务限流和故障模拟。今天和大家谈谈限流算法的几种实现方式,本文所说的限流并非是Nginx层面的限流,而是业务代码中的逻辑限流。
那么为什么需要限流呢?
按照服务的调用方,可以分为以下几种类型服务
1、与用户打交道的服务
比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮:
用户增长过快(这是好事)
因为某个热点事件(微博热搜)
竞争对象爬虫
恶意的刷单
这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量打进来,如果真碰上这种情况,扩容是根本来不及的(弹性扩容都是虚谈,一秒钟你给我扩一下试试)。
2、对内的RPC服务
一个服务A的接口可能被BCDE多个服务进行调用,在B服务发生突发流量时,直接把A服务给调用挂了,导致A服务对CDE也无法提供服务。 这种情况时有发生,解决方案有两种:
每个调用方采用线程池进行资源隔离
使用限流手段对每个调用方进行限流
二、限流算法简介
限流即流量限制,也叫做流量整形。限流的目的是在遇到流量高峰期或者流量突增(流量尖刺)时,通过对流量速率进行限制,当达到限制速率时,可以拒绝服务(定向到错误页或告知资源没有了)、排队或等待(比如秒杀、评论、下单)、降级(返回兜底数据或默认数据,如商品详情页库存默认有货)。以把流量控制在系统所能接受的合理范围之内,不至于让系统被高流量击垮。
三、常见限流算法
常用的限流算法大致有三种:漏桶算法、令牌桶算法、计数器算法
1.漏桶算法
漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolicing),漏桶算法的描述如下:
一个固定容量的漏桶,按照常量固定速率流出水滴
如果桶是空的,则不需流出水滴
可以以任意速率流入水滴到漏桶
如果流入水滴超出了桶的容量,则流入的水滴溢出了(被丢弃),而漏桶容量是不变的