用Redis咋能防止页面老刷新的问题,简单聊聊思路和方法
- 问答
- 2026-01-17 11:19:36
- 2
用Redis防止页面老刷新的问题,说白了就是对付那些过于频繁的、没必要的请求,比如你做一个抽奖按钮,用户点一下就应该等结果,但他可能心急,咔咔咔连着按好几下,或者更恶劣的,有人写个脚本不停地刷你的某个接口,想薅羊毛或者把你的网站搞慢,这时候Redis就能派上大用场,因为它特别快,适合用来做这种频繁的计数和判断。
核心思路其实就一句话:在用户进行操作之前,先让Redis帮忙查一下“户口”,看看他最近是不是太活跃了,如果太频繁了,就让他等会儿再来。
下面我聊聊几种常见又实用的方法。
第一个最直接的方法,叫“计数限流”。 这个很好理解,就像你去银行办业务,柜员告诉你“您这个号码今天只能办三次业务”,具体怎么做呢?就是给每个用户或者每个IP地址针对某个操作(请求文章详情页”、“提交订单”)设一个计数器,用户每来一次,这个计数器就加1,我们给这个计数器设置一个过期时间,比如1分钟。

举个例子,用户A的IP是192.168.1.1,他要访问/api/news/123这个文章接口,我们就在Redis里创建一个键(Key),可以叫rate_limit:192.168.1.1:/api/news/123,他第一次访问时,这个键的值变成1,并且设置60秒后自动删除,如果他在1分钟内又访问了第二次,值就变成2,假如我们设定1分钟内最多允许访问10次,那么当他的第11次请求过来时,我们一查Redis,发现值已经大于10了,就直接返回一个错误提示,您的操作过于频繁,请稍后再试”,等60秒一过,这个键自动没了,相当于“解封”了,他又可以重新开始访问,这个方法简单粗暴,非常有效,根据Redis官方文档对INCR命令和过期时间EXPIRE的介绍,这种组合是实现限流的基础。
第二个方法,稍微高级一点,叫“滑动窗口限流”。 刚才的计数限流有个小缺点,就是它是以一个固定的时间窗口(比如刚说的1分钟)来算的,假设用户在窗口的最后1秒发起了10次请求,紧接着下一秒(新的窗口刚开始)又发起10次请求,那在短短两秒内他就实际请求了20次,但还是通过了检查,因为分属两个不同的时间窗口,这就不够平滑。
滑动窗口就是为了解决这个问题的,它不像固定窗口那样“一刀切”,而是看最近一段时间内的总请求数,实现起来稍微复杂点,但用Redis也能做,一种常见的思路是使用有序集合(Sorted Set),我们把每次请求的时间戳作为分数(score)存进去,当新的请求来时,我们先移除掉时间窗口(比如1分钟)之前的所有旧时间戳,然后统计集合里还剩下多少個时间戳,这个数量就是最近1分钟内的请求数,如果数量超过了限制,就拒绝请求;如果没超过,就把当前时间戳加进去,这样,我们始终检查的是“当前时间点往前推1分钟”这个滑动窗口内的请求量,更加精准,这个方法是流控算法中的经典实践,在Github等开源项目的API限流设计中常能见到其思想。

第三个方法,针对“重复提交”的场景,叫“令牌机制”或者“设置状态锁”。 这特别适合防止比如重复下单、重复抽奖这种问题,思路是,当用户开始一个操作时,我们立刻在Redis里给他占个“坑”,告诉他“这个位置你已经占了,正在处理中,别再来占了”。
具体做的时候,可以在用户加载页面时,后端生成一个唯一的令牌(Token),同时把这个令牌存到Redis里,并设置一个较短的过期时间(比如30秒),然后把这个令牌返回给前端页面,当用户点击按钮提交时,必须把这个令牌一起带过来,后端收到请求后,首先去Redis里找这个令牌是否存在,如果存在,说明是第一次提交,然后立刻把Redis里的这个令牌删掉,再开始处理业务(比如扣减库存、记录中奖信息),如果Redis里已经没了(可能是因为已经处理过一次被删了),就直接返回“请勿重复提交”的提示,这样即使用户手再快,连续发起了两次请求,第二次请求也会因为令牌已被删除而失败,这种做法利用了Redis的SETNX(Set if not exists)或直接SET后立即删除的原子性操作,确保了逻辑的可靠性,在电商秒杀等场景中应用广泛。
还有一个更简单的思路,对于防止刷新爬虫特别有用,缓存结果”。 有些页面内容其实并不需要实时更新,比如文章详情、商品介绍页,如果有个别用户或者爬虫疯狂刷新同一个页面,每次都要去数据库查,数据库压力就很大,我们可以用Redis把第一次查询的结果缓存起来,设置一个比如5分钟的过期时间,在这5分钟内,所有对这个页面的请求,都直接从这个缓存里取结果返回,这样,无论对方刷得多快,实际上只有第一次请求打到了数据库,后面的请求都由Redis这个高速缓存接住了,大大减轻了后端负担,这是Redis作为缓存数据库最核心的用途,在Redis官网的用例说明中位列首位。
用Redis防刷新,主要就是利用它超快的读写速度和灵活的数据结构(字符串计数、有序集合、集合等),在请求真正处理业务逻辑之前,加一层“安检”,无论是简单的计数,还是更精细的滑动窗口,或者是防止重复提交的令牌,核心都是把判断逻辑前移到Redis这个高速层,从而保护后方更脆弱的数据库和应用服务器,具体用哪种方法,就看你的业务场景最怕哪种“刷”了。
本文由畅苗于2026-01-17发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/82378.html
