接口限流那事儿,怎么用Redis来搞起来的实践分享
- 问答
- 2025-12-29 22:31:32
- 4
这事儿还得从我们那个用户签到领积分的小程序说起,一开始用户少,相安无事,后来搞了个活动,用户量一下子上来了,结果你猜怎么着?我们的签到接口直接挂掉了,后来查原因,根本不是数据库撑不住,就是单纯的请求太多了,服务器处理不过来,就像一条小路上突然涌进千军万马,全堵死了,谁也过不去。
老司机一看就说,这是典型的没做“接口限流”,说白了,就是得给每个用户或者每个接口设定一个访问频率的上限,比如一分钟内只能请求60次,超过这个数,就让他等会儿再来,别一股脑全冲进来,这样既能保护服务器,也能保证大多数正常用户能顺畅使用。
那为啥选Redis呢?主要是因为它快,限流这个操作,本身就是在每次请求时都要去检查一下“计数”,这个检查动作必须非常快,不能比处理业务逻辑还慢,否则就本末倒置了,Redis的数据都在内存里,速度没得说,而且它自带的某些特性特别适合干这个事儿。

下面我就说说我们实际用过的两种用Redis搞限流的方法,都很实在。
第一种方法,叫“固定窗口计数器”,这个最好理解。 (来源:常见的限流算法思想)
思路是这样的:我们把时间切成一个一个的窗口,比如一分钟一个窗口,对每一个接口+用户(可以用用户ID做Key的一部分),在Redis里设置一个计数器,当一个请求过来时,我们就用Redis的命令给这个计数器加1,我们给这个Key设置一个一分钟的过期时间。

伪代码大概是这样的:
key = "limit:sign_in:" + userIdcurrent_count = redis.incr(key)// 给计数器加1,并返回当前值if current_count == 1 then// 如果是这个窗口的第一个请求redis.expire(key, 60)// 设置这个Key在60秒后过期end ifif current_count > 60 thenreturn "请求太频繁,请稍后再试"// 限流elsereturn "签到成功"// 正常处理业务end if
这个方法简单粗暴,实现起来特别快,我们最开始就是用这个救急的,但它有个明显的毛病,窗口切换”的时候不够平滑,比如在0:59秒的时候,来了60个请求,这时计数器满了,触发了限流,但紧接着到了1:00秒,窗口重置,计数器从0开始,又可以接受60个请求,要是在0:59和1:00这两秒内,瞬间来了120个请求,服务器照样可能扛不住,这就好比一个水龙头,前一分钟最后几秒和下一分钟最开始几秒的流量叠加,可能会冲垮水管。
为了解决这个边界问题,我们又用了第二种更高级点的方法,叫“滑动窗口”。 (来源:更精细的限流算法实现)

这个想法更聪明一点,它不像固定窗口那样一刀切,而是记录下最近一段时间内(比如一分钟)的每一次请求的时间戳,当一个新的请求到来时,我们不是只看一个固定的窗口,而是“滑动”这个窗口,只统计当前时间点往前推一分钟内的请求数量,如果这个数量没超过限制,就放行。
直接用Redis的List或者ZSet(有序集合)都能实现,我们用ZSet更顺手,把每次请求的时间戳作为分数(score)存进去。
伪代码:
key = "sliding_limit:sign_in:" + userIdnow = System.currentTimeMillis()// 当前时间戳window_size = 60000// 窗口大小,60秒,单位毫秒redis.zremrangeByScore(key, 0, now - window_size)// 核心一步:清除掉所有超过一分钟之前的旧时间戳,只保留窗口内的current_count = redis.zcard(key)// 计算当前窗口内还剩多少请求记录if current_count < 60 thenredis.zadd(key, now, now)// 把本次请求的时间戳加进去,这里用时间戳同时当成员和分数,因为要唯一redis.expire(key, 60)// 设置过期时间,避免冷数据长期占用内存return "签到成功"elsereturn "请求太频繁,请稍后再试"end if
这个方法的好处是精度高,能很好地解决固定窗口在边界时间段的流量突刺问题,因为它统计的是动态滑动的最近一分钟,而不是僵化的整点分钟,缺点嘛,就是比固定窗口稍微耗一点Redis的资源,因为每次都要清理旧数据,但对我们来说,用这点资源换来服务的稳定,是完全值得的。
最后还得提一嘴,这些限流的Key最好都设置上过期时间,不然Redis里会存满大量已经不再活跃的用户数据,我们就是通过这两种方法,特别是滑动窗口,把接口限流这事儿给搞定了,之后再搞活动,心里就踏实多了,具体用哪种,还得看你的业务场景,如果对边界问题不敏感,固定窗口的简单性也有它的优势。
本文由邝冷亦于2025-12-29发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/70906.html
