Redis滑动窗口限流,守护系统稳定,让每一次访问都从容有序,技术护航,服务更流畅。

文章导读
在高并发场景下,使用Redis实现滑动窗口限流是守护系统稳定的关键方法。通过Redis的有序集合ZSET,我们可以记录每个请求的时间戳,在固定时间窗口内统计请求次数,如果超过阈值就拒绝请求,确保每一次访问都从容有序。下面是一个简单的Java代码示例:
📋 目录
  1. 使用Redis ZSET实现滑动窗口限流
  2. Spring Boot集成Redis滑动窗口限流
  3. Redis滑动窗口限流的优缺点
  4. 实战案例:电商秒杀限流
  5. Go语言Redis滑动窗口限流代码
  6. 监控和优化建议
A A

在高并发场景下,使用Redis实现滑动窗口限流是守护系统稳定的关键方法。通过Redis的有序集合ZSET,我们可以记录每个请求的时间戳,在固定时间窗口内统计请求次数,如果超过阈值就拒绝请求,确保每一次访问都从容有序。下面是一个简单的Java代码示例:

import redis.clients.jedis.Jedis;
public class SlidingWindowRateLimiter {
private Jedis jedis;
private String key;
private int windowSize;
private int maxRequests;
public SlidingWindowRateLimiter(Jedis jedis, String key, int windowSize, int maxRequests) {
this.jedis = jedis;
this.key = key;
this.windowSize = windowSize;
this.maxRequests = maxRequests;
}
public boolean isAllowed() {
long now = System.currentTimeMillis() / 1000;
double windowStart = now - windowSize;
jedis.zremrangeByScore(key, 0, windowStart);
long currentCount = jedis.zcard(key);
if (currentCount < maxRequests) {
jedis.zadd(key, now, String.valueOf(now));
jedis.expire(key, windowSize);
return true;
}
return false;
}
}

使用Redis ZSET实现滑动窗口限流

滑动窗口限流利用Redis的ZSET数据结构,每个成员是请求的时间戳(score),通过ZREMRANGEBYSCORE移除窗口外的旧请求,ZCARD获取当前窗口内请求数。如果不超过阈值,就ZADD当前时间戳。这种方式比固定窗口更平滑,避免了边界突刺流量。

Spring Boot集成Redis滑动窗口限流

在Spring Boot中,可以用注解方式实现限流。定义一个RateLimiter切面,拦截请求,调用Redis滑动窗口逻辑。配置窗口大小为60秒,每分钟最多100次请求。高峰期自动限流,低峰期正常放行,服务流畅无压力。

Redis滑动窗口限流,守护系统稳定,让每一次访问都从容有序,技术护航,服务更流畅。

Redis滑动窗口限流的优缺点

优点:精度高,支持分布式,实时性好。缺点:ZSET操作稍慢于计数器,对内存有消耗。适用于API网关、秒杀等场景。实际生产中,结合漏桶或令牌桶使用效果更好。

实战案例:电商秒杀限流

在双11秒杀活动中,用Redis滑动窗口对用户IP限流,每用户1分钟10次请求。ZADD时间戳,ZREMRANGEBYSCORE清理,超过就返回429。系统稳定,订单顺利下单,用户体验丝滑。

Redis滑动窗口限流,守护系统稳定,让每一次访问都从容有序,技术护航,服务更流畅。

Go语言Redis滑动窗口限流代码

package ratelimit
import "github.com/redis/go-redis/v9"
func (r *SlidingWindow) Allow(ctx context.Context) bool {
now := time.Now().Unix()
start := now - int64(r.Window)
r.client.ZRemRangeByScore(ctx, r.Key, "-inf", strconv.Itoa(int(start))).Result()
count, _ := r.client.ZCard(ctx, r.Key).Result()
if count < int64(r.Capacity) {
r.client.ZAdd(ctx, r.Key, redis.Z{Score: float64(now), Member: strconv.Itoa(int(now))}).Result()
return true
}
return false
}

监控和优化建议

部署Prometheus监控Redis键的数量和命中率,设置告警。优化时用pipeline批量操作,减少RTT。窗口大小根据业务调优,1分钟到1小时不等,确保技术护航服务流畅。

FAQ
Q: 滑动窗口和固定窗口有什么区别?
A: 滑动窗口随时间滑动,更均匀;固定窗口在边界可能突增流量。
Q: Redis内存消耗大吗?
A: 每个请求一个score,窗口内高并发下几KB,可接受,定期清理。
Q: 支持分布式吗?
A: 是的,单Redis实例即可,多实例用集群。
Q: 怎么设置窗口大小?
A: 根据QPS需求,如1分钟100次,windowSize=60,maxRequests=100。