问题简要描述
由于代码里使用ZCOUNT统计key的数量来当作请求数量,同一毫秒内的多个请求会被按照一个进行计算。1秒内最多只有1000毫秒,因此如果我设置1秒内最多允许3000请求,那么这个条件永远不会成立。因为即使1秒进来10W个请求,ZCOUNT也只能拿到1000个key。这个问题把时间单位从毫秒改为微秒/纳秒可以一定程度上的缓解吗,但治标不治本,实测下来,连续请求100个,ZCOUNT拿到的值也不到100个。
复现步骤
func main() {
client := redis.NewClient(&redis.Options{
Addr: "local.machine:6379",
})
rdsLimiter := RedisSlidingWindowLimiter{
Cmd: client,
Interval: time.Second,
Rate: 100, // 每秒允许100个
}
var (
total = 1500 // 总请求数
succ int // 成功请求数
limited int // 被限流的请求数
)
start := time.Now()
for i := 0; i < total; i++ {
limit, err := rdsLimiter.Limit(context.Background(), "test")
if err != nil {
log.Printf("limit error: %v", err)
return
}
if limit {
limited++
log.Printf("%4d号请求被限流了", i)
continue
}
succ++
}
end := time.Now()
log.Printf("开始时间: %v", start.Format(time.StampMilli))
log.Printf("结束时间: %v", end.Format(time.StampMilli))
log.Printf("total: %d, succ: %d, limited: %d", total, succ, limited)
}
错误日志或者截图

你期望的结果
100个通过,剩下全部限流
你排查的结果,或者你觉得可行的修复方案
同一时间内多个请求进行自增记录,统计时使用窗口时间内,请求数量的和。或为每个请求生成一个随机uuid, 这样即使同一时间进来两个请求,由于uuid不同,在计算时它们还是会被当作两次请求计算
问题简要描述
由于代码里使用
ZCOUNT统计key的数量来当作请求数量,同一毫秒内的多个请求会被按照一个进行计算。1秒内最多只有1000毫秒,因此如果我设置1秒内最多允许3000请求,那么这个条件永远不会成立。因为即使1秒进来10W个请求,ZCOUNT也只能拿到1000个key。这个问题把时间单位从毫秒改为微秒/纳秒可以一定程度上的缓解吗,但治标不治本,实测下来,连续请求100个,ZCOUNT拿到的值也不到100个。复现步骤
错误日志或者截图
你期望的结果
100个通过,剩下全部限流
你排查的结果,或者你觉得可行的修复方案
同一时间内多个请求进行自增记录,统计时使用窗口时间内,请求数量的和。或为每个请求生成一个随机uuid, 这样即使同一时间进来两个请求,由于uuid不同,在计算时它们还是会被当作两次请求计算