经验分享

谈谈接口中的几种限流实现

为什么需要限流按照服务的调用方,可以分为以下几种类型服务 1、与用户打交道的服务比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮:用户增长过快(这是好事)因为某个热点事件(微博热搜)竞争对象爬虫恶意的刷单这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量进来,如果遇到此类情况,扩容是根本来不及的,弹性扩容也是来不及的; 2、对内的RPC服务一


为什么需要限流

按照服务的调用方,可以分为以下几种类型服务

 

1、与用户打交道的服务

比如web服务、对外API,这种类型的服务有以下几种可能导致机器被拖垮:

用户增长过快(这是好事)

因为某个热点事件(微博热搜)

竞争对象爬虫

恶意的刷单

这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量进来,如果遇到此类情况,扩容是根本来不及的,弹性扩容也是来不及的;

 

2、对内的RPC服务

一个服务A的接口可能被BCDE多个服务进行调用,在B服务发生突发流量时,直接把A服务给调用挂了,导致A服务对CDE也无法提供服务。 这种情况时有发生,解决方案有两种: 1、每个调用方采用线程池进行资源隔离 2、使用限流手段对每个调用方进行限流

 

限流算法实现

常见的限流算法有:计数器、令牌桶、漏桶。

 

1、计数器算法

采用计数器实现限流有点简单粗暴,一般我们会限 制一秒钟的能够通过的请求数,比如限流qps为100,算法的实现思路就是从第一个请求进来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到了100,那么后续的请求就会被全部拒绝。等到1s结束后,把计数恢复成0,重新开始计数。

 

具体的实现可以是这样的:对于每次服务调用,可以通过 AtomicLong#incrementAndGet()方法来给计数器加1并返回最新值,通过这个最新值和阈值进行比较。

 

这种实现方式,相信大家都知道有一个弊端:如果我在单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能眼巴巴的把请求拒绝,我们把这种现象称为“突刺现象”

 

2、漏桶算法

为了消除"突刺现象",可以采用漏桶算法实现限流,漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终

原创不易,完成人机校验,阅读全文

相关推荐