常见的服务限流算法-yb体育官方

yb体育官方-亚博平台app下载 我们 服务 网站建设 移动应用 案例 资讯 联系
业务专线:

期待聆听您的声音

15989169178

不忽悠,不作恶,不欺诈;敬天理,存良知,思利他。
服务网点:广州 深圳 佛山 粤西

与我们一起分享美好

常见的服务限流算法

发布时间:2023-02-23 发布作者:睿思设计 查阅次数:167次 标签:

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


服务降级


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


服务限流


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


本篇文章中说到的服务限流不是 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 次计数仍然是有效的,所以,这个时间段新的请求仍然会被拒绝。


漏桶算法


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

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


令牌桶算法


在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌才有机会继续执行,否则请求选择等待或者服务直接拒绝请求。


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

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


上面我们提到的限流算法主要是针对于单机限流,实际业务场景更加的复杂,业务的需求五花八门,简单的单机限流很难满足需求。


比如为了限制某个资源被某个用户访问的次数,10 s 只能访问 3 次,或者一天只能访问 100 次,这种需求通过单机限流是无法实现的,这时就需要通过集群限流的方式实现。


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


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


对于排名不稳定的老网站优化应该怎么做?

我们的位置

广州 广州市黄埔区科学城科学大道18号芯大厦

深圳 深圳市南山区大冲国际中心九楼

粤西 茂名市茂南区油城三路粤西创业创新孵化基地b110

亚博平台app下载的服务

网站及移动应用 高端品牌网站 app开发 小程序开发 微信运营

系统应用开发 oa/erp/crm/hr系统开发

了解我们

yb体育官方的简介 联系亚博平台app下载 我们的案例 新闻资讯

© 2009-2023 广州睿网信息科技有限公司 yb体育官方的版权所有 

网站地图