限流概述
一、为什么要限流?
削峰,降并发
二、限流的概念
博客:https://blog.csdn.net/liuerchong/article/details/118882053
三、有哪些限流算法?
1、令牌桶
主要有一下两个角色:
令牌:获取到令牌的request才会被处理,其他的要么排队要么丢弃。
桶:用来装令牌的地方,所有request都从这个桶里面获取令牌。
在令牌发放器就是一个水龙头,假如在下面接水的桶子满了,那么自然这个水(令牌)就流到了外面。在令牌发放过程中也一样,令牌桶的容量是有限的,如果当前已经放满了额定容量的令牌,那么新来的令牌就会被丢弃掉。
2、漏桶
漏桶是将访问请求的数据包放到桶里。同样的是,如果桶满了,那么后面新来的数据包将被丢弃。
漏桶算法的后半程是有鲜明特色的,它永远只会以一个恒定的速率将数据包从桶内流出。打个比方,如果我设置了漏桶可以存放100个数据包,然后流出速度是1s一个,那么不管数据包以什么速率流入桶里,也不管桶里有多少数据包,漏桶能保证这些数据包永远以1s一个的恒定速度被处理。
漏桶 vs 令牌桶的区别
根据它们各自的特点不难看出来,这两种算法都有一个“恒定”的速率和“不定”的速率。令牌桶是以恒定速率创建令牌,但是访问请求获取令牌的速率“不定”,反正有多少令牌发多少,令牌没了就干等。而漏桶是以“恒定”的速率处理请求,但是这些请求流入桶的速率是“不定”的。
从这两个特点来说,漏桶的天然特性决定了它不会发生突发流量,就算每秒1000个请求到来,那么它对后台服务输出的访问速率永远恒定。而令牌桶则不同,其特性可以“预存”一定量的令牌,因此在应对突发流量的时候可以在短时间消耗所有令牌,其突发流量处理效率会比漏桶高,但是导向后台系统的压力也会相应增多。
3、滑动窗口(计数器)
将一个时间窗口分为5份。每一份里面都有一个独立计数器c。在时间轴上的一个时间窗口内,没当请求过来的时候,就会求计数器 c1+c2+c3+c4+c5的和,当达到阀值就拒绝,没达到当前小格子里面的计数器就加1 。
当时间窗口滑动一小格后如下:
这是会重新计算这个窗口内所有时间小格子中的计数记录的请求数之和,当达到阀值之后,就不拒绝访问。因此当1.0到1.2这个格子中出现10个请求时,只能放1个请求进来,拒绝9个。
这样可以有效避免固定窗口算法中的问题。当格子划分的越小,这个滑动窗口就越平滑。请求就越均匀。但是达到阀值就拒绝,这个在实际业务场景中过于暴力。因此这个算法也不是最理想的解决方案。
限流方案:
合法性验证限流
比如验证码、IP 黑名单等,这些手段可以有效的防止恶意攻击和爬虫采集;
Guava限流
谷歌开源的单机限流器
网关层限流
1.用户流量从网关层转发到后台服务
2.后台服务承接流量,调用缓存获取数据
3.缓存中无数据,则访问数据库
Nginx限流
中间件限流-redis
对于分布式环境来说,无非是需要一个类似中心节点的地方存储限流数据。打个比方,如果我希望控制接口的访问速率为每秒100个请求,那么我就需要将当前1s内已经接收到的请求的数量保存在某个地方,并且可以让集群环境中所有节点都能访问。那我们可以用什么技术来存储这个临时数据呢?
那么想必大家都能想到,必然是redis了,利用Redis过期时间特性,我们可以轻松设置限流的时间跨度(比如每秒10个请求,或者每10秒10个请求)。同时Redis还有一个特殊技能–脚本编程,我们可以将限流逻辑编写成一段脚本植入到Redis中,这样就将限流的重任从服务层完全剥离出来,同时Redis强大的并发量特性以及高可用集群架构也可以很好的支持庞大集群的限流访问。【reids + lua】
限流组件
除了上面介绍的几种方式以外,目前也有一些开源组件提供了类似的功能,比如Sentinel就是一个不错的选择。Sentinel是阿里出品的开源组件,并且包含在了Spring Cloud Alibaba组件库中,Sentinel提供了相当丰富的用于限流的API以及可视化管控台,可以很方便的帮助我们对限流进行治理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话