什么是限流器以及常见的服务限流算法

在开发高并发系统的时候,我们一般通过三种方式去保障系统服务稳定:服务降级、服务限流和缓存。对于缓存在实际开发中使用的比较多,这个是大家的共识没有什么异议的。今天我们的主角是服务限流,在此之前我们先来看下服务限流服务降级 的区别:
服务降级

服务降级是在服务器压力陡增的情况下,利用现有的资源,关闭一些服务接口或者页面,以此来释放服务器资源保证核心任务的正常运行

服务限流

限流本质上是减少流量的访问,而服务的处理能力不变;而对于服务降级来说是降低了部分服务的处理能力,增加另一部分服务处理能力,访问量不变

本篇文章中说到的服务限流不是 nginx 层面的限流,而是业务代码中的逻辑限流。

那么,我们为什么要服务限流?

从服务调用方来说,可以把服务简单的划分为以下几种类型的服务
1.与用户打交道的服务
比如 web 服务,对外 API,这种类型的服务有以下几种可能会导致服务器压力变大:

  • 用户增长过快
  • 热点事件
  • 恶意的攻击/刷单
  • 爬虫
    这些情况都是无法预知的,我们不知道什么时候请求流量会突增,如果真的要是碰到这种情况,扩容根本是来不及的
    2.对内的 RPC 服务
    一个服务 A 的接口可能会被其他 BCDE 多个服务调用,如果其中一个服务的流量突增比如 B 服务,导致 A 服务压力变大甚至挂掉,那么这个时候也不能给 CDE 服务提供服务
    这种情况在实际开发中时常发生
常见的限流算法

下面我们来看几种实际业务场景中常用的几种限流算法:计数器算法、漏桶算法、令牌桶算法

计数器算法

计数器算法应该是最简单,最容易想到的限流策略。限流的本质是限制某一个 API 在某个维度单位时间内处理请求的次数。我们可以设置一个计数器对某一时间段内的请求进行计数,当请求量超过事先设定好的阈值,拒绝用户的请求。比如限流的 QPS 是100,算法的实现思路是从第一个请求进来开始计数,在接下来的 1s 内,每来一个请求计数器自动加 1,如果累加的数字超过 100,那么后续的请求就会被拒绝,等到 1s 结束后,计数器开始重置为 0,重新开始计数。
这种方式存在弊端
弊端1:如果在 1s 的前 10ms 请求数已经达到了 100,那么剩下的 990ms,服务调用方就要眼巴巴的看着请求被拒绝
弊端2:如果有一个恶意的用户在 999ms 的时候瞬间发送了 100 次请求,并且又在 1000ms 时瞬间发送了 100 次请求,那么其实这个用户在 1s 内发送了 200 次请求。利用时间窗口的重置节点处突发请求,可以瞬间超过我们服务本身能承受的压力,瞬间压垮服务

针对计数器算法的漏洞一个比较经典的处理方案是采用 滑动窗口。比如我们把上面的 1min 内 100 次请求上限看成是一个大的时间窗口,然后把这个窗口进一步细分,比如每 10 s 一个小窗口,该窗口的频率上限同样设置成 100,这样大窗口包含 16 个小窗口,并且每过 10s 大窗口就移动一个小窗口长度。如果一个恶意用户在 09:59:30~09:59:59 之间发送了 100 次请求,等到了10:00:00~10:00:30 时 100 次计数仍然是有效的,所以,这个时间段新的请求仍然会被拒绝

漏桶算法

漏桶算法是限流方面比较经典的算法。可以把该算法联想成一个具体的漏桶模型,漏桶始终以一个恒定的速率往外排水,如果桶被装满的话则后来涌入的水会溢出。对应到接口限流来说,用户的请求可以看做是水,不管用户的请求量有多大多不均衡,能够被处理的请求速率是恒定的,而且能够接受的请求数也是有上限的,超出上限的请求会被拒绝,在算法实现方面可以准备一个队列来作为漏桶的实现,用这个队列保存请求,通过一个线程池定期从队列中获取请求并执行,也可以一次性获取多个并发请求,如下图:


3105959844-5aee9977a149e_articlex.jpeg

漏桶算法也存在一个弊端:无法应对短时间的突发流量

令牌桶算法

在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌才有机会继续执行,否则请求选择等待或者服务直接拒绝请求
放令牌这个动作是持续不断的进行,如果桶中令牌数量达到上限,就丢弃令牌,所以,会存在这样的一种情况,桶中一直有大量的令牌,这时进来的请求就可以直接拿到令牌执行。比如我们把 QPS 设置成 100,那么限流器完成初始化 1s 后,桶中已经有 100 个令牌,这时候服务还未完全启动好,等启动完成功对外提供服务时,该限流器可以抵挡瞬时的 100 个请求。所以,当桶中没有令牌时请求才会等待或者被拒绝,当没有请求申请令牌时,那么这个令牌桶会溢出。在这里令牌桶类似一个 buffer,请求密度比较低或者处于冷却状态下,令牌桶会溢出,当请求流量突增时,则过去积累的结余资源直接可以拿来借用,从这里可以看出这点弥补了漏桶算法的不足


640.png

实现思路:可以准备一个队列,用于存放令牌,另外通过一个线程池定期生成令牌存放到队列中,没来一个请求就从队列中取出一个令牌,并继续执行

上面我们提到的限流算法主要是针对于单机限流,实际业务场景更加的复杂,业务的需求五花八门,简单的单机限流很难满足需求。
比如为了限制某个资源被某个用户访问的次数,10 s 只能访问 3 次,或者一天只能访问 100 次,这种需求通过单机限流是无法实现的,这时就需要通过集群限流的方式实现

如何实现?为了实现对访问次数的限制,肯定需要一个计数器,那么我们需要把这个计数器放在哪里呢?因为这个限流是在集群层面实现的,集群形式存在的情况才需要分布式限流,由于 redis 天生对分布式支持非常友好,所以 redis 成了一个很好的选择

大致思路:每次有相关的操作时候,我们就向 redis 服务器发送一个 incr 命令。比如限制某个用户访问接口的次数,当用户请求过来时我们使用用户 ID 和 接口名称生成对应 key,每次该用户访问这个接口时,只需要对这个 key 增加 1,并且给这个 key 设置有效期,这样就可以简单的实现指定时间内的访问效率

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容