用Redis做请求流量管控,简单聊聊限流那些事儿
- 问答
- 2025-12-26 18:32:03
- 1
说到用Redis做请求流量管控,其实就是我们常说的“限流”,这玩意儿听起来好像挺高大上,但其实道理很简单,想象一下你开了一家特别火的奶茶店,店里只有两个员工能做奶茶,如果一下子涌进来一百个客人点单,那两个员工肯定忙不过来,订单会堆积如山,后面的客人等得不耐烦,员工也累得够呛,整个店就瘫痪了,限流就是店门口那个维持秩序的保安,他告诉客人:“不好意思,里面最多只能容纳10个人排队,后面的客人请稍等一会儿。”
在互联网世界里,我们的服务器就像那家奶茶店,它的处理能力是有限的,如果突然间有海量的请求(比如双十一抢购、某个明星爆出大新闻导致大家疯狂刷微博)涌向服务器,服务器可能就会因为处理不过来而崩溃,导致所有用户都无法访问,这就是“雪崩效应”,限流就是为了保护服务器,确保它在高负载下也能稳定运行,至少能保证一部分用户(比如已经成功排上队的)能正常使用服务。
Redis为什么特别适合做这件事呢?主要因为它有两个宝贝特点:速度快和能设置过期时间,限流这个动作需要在极短的时间内完成判断(这个用户能不能通过),所以负责限流的工具本身必须非常快,不能成为新的瓶颈,Redis的数据都在内存里,读写速度是微秒级别的,完全能满足要求,限流通常是在一个时间窗口内计数(比如一分钟内最多允许请求60次),Redis可以给存储的计数设置过期时间,时间一到自动删除,非常方便。
我们聊聊几种简单实用的限流思路,这些方法在网上很多技术博客,比如知乎、CSDN上都有详细的讨论和代码实现。
第一种,计数器法。 这是最直白的一种,我想限制某个API接口一分钟内只能被同一个IP访问60次,具体怎么做呢?我在Redis里给这个IP创建一个键(key),比如叫 rate_limit:192.168.1.1,它的值就是访问次数,每次这个IP来请求,我就执行两步操作:1. 把它的值加一,2. 如果这个键是刚创建的(说明是这一分钟内的第一次请求),我就设置这个键60秒后过期,然后我判断一下,如果加一后的值大于60了,就说明超限了,拒绝请求;如果没超过,就正常处理,这个方法简单易懂,但有个小缺点:它不够平滑,想象一下,在上一分钟的最后1秒和下一分钟的第1秒,这两秒内用户其实可以瞬间发出120次请求,可能会对系统造成冲击。
第二种,滑动窗口法。 这个方法是为了解决计数器法不够平滑的问题,它把时间窗口划分成更小的格子,把一分钟分成6个10秒的格子,每个格子独立计数,当一个新的请求到来时,它会统计当前时间点往前推一分钟内,所有小格子的请求数总和,如果总和超过60,就限流,它会清理掉那些已经超出一分钟范围的旧格子,这样,限流判断就变得更加精确和平滑了,Redis可以用有序集合(Sorted Set)来实现这个逻辑,把时间戳作为分数,请求标识作为成员,通过计算某个时间范围内的成员数量来统计请求数,这种方法比计数器法更公平,但实现起来稍微复杂一点。
第三种,令牌桶算法。 这个算法在业界用得非常多,比如Google的Guava库就有现成的实现,它的思路很有意思:想象有一个桶,这个桶的容量是固定的(比如能装100个令牌),然后系统以一个固定的速率(比如每秒10个)往桶里扔令牌,当有请求到来时,就需要从桶里拿走一个令牌,如果桶里有令牌,请求就可以通过;如果桶是空的,那就说明这段时间请求太快了,令牌已经被拿光了,请求就会被拒绝,这个算法的妙处在于,它允许一定程度的“突发流量”,因为如果一段时间没有请求,桶里的令牌会累积起来,最多能累积到100个,这样,当突然来了一波请求时,只要桶里有足够的令牌,这些请求都可以立即被处理,而不是被卡死,用Redis实现令牌桶,我们可以存储两个值:一个是当前桶内的令牌数量,另一个是上次补充令牌的时间戳,每次请求来时,先计算自上次补充后应该新加多少令牌,更新桶内令牌数,然后再进行扣减判断。
第四种,漏桶算法。 这个算法和令牌桶有点像,但思路相反,它也是一个桶,但请求进来像是水流入桶中,而桶的底部有一个固定大小的孔,以恒定的速率漏出水(处理请求),无论上游的请求流量多大、多猛烈,从桶里流出的请求速率始终是恒定的,如果流入的请求太快,桶满了,多出来的水(请求)就会溢出去,也就是被拒绝掉,这个算法的主要作用是保证请求被处理的速率是绝对均匀的,适合用来保护下游的系统,Redis也可以用列表(List)等数据结构来模拟这个漏桶。
在实际应用中,选择哪种方法要看具体的场景,如果只是做一个简单的API调用次数限制,计数器法可能就够用了,如果要应对突发流量,希望系统有一定弹性,令牌桶会更合适,如果要严格平滑流量,保护后端,漏桶是更好的选择。
最后要提一句,限流虽然好,但不能乱用,它本质上是一种“有损”的保护措施,意味着它会拒绝掉一部分用户的请求,在触发限流时,给用户一个友好的提示(系统繁忙,请稍后再试”)是非常重要的,也要合理地设置限流的阈值,既不能太松起不到保护作用,也不能太严影响正常用户的使用,这就需要我们不断地监控系统的负载和性能,进行调整和优化了。 结束)

本文由瞿欣合于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/68944.html
