Redis实现滑动窗口限流

本文介绍了如何使用Redis实现滑动窗口算法进行限流,以及在Java中通过注解和切面编程实现灵活的限流策略,包括全局限流、IP限流和用户限流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常见限流算法

  1. 固定窗口算法

    在固定的时间窗口下进行计数,达到阈值就拒绝请求。固定窗口如果在窗口开始就打满阈值,窗口后半部分进入的请求都会拒绝。

  2. 滑动窗口算法

    在固定窗口的基础上,窗口会随着时间向前推移,可以在时间内平滑控制流量,解决固定窗口出现的突发流量问题。

  3. 漏斗算法

    请求来了先进入漏斗,漏斗以恒定的速率放行请求。

  4. 令牌桶算法

    在令牌桶中,以恒定的速率放入令牌,令牌桶也有一定的容量,如果满了令牌就无法放进去了。拿到令牌的请求通过,并消耗令牌,如果令牌桶中令牌为空,则会丢弃该请求。

redis实现滑动窗口算法

当有请求来的时候记录时间戳,统计窗口内请求的数量时只需要统计redis中记录的数量。可以使用redis中的zset结构来存储。key可以设置为请求的资源名,同时根据限流的对象,往key中加入限流对象信息。比如根据ip限制访问某个资源的流量,可以使用方法名+ip作为key。score设置为时间戳。value则可以根据请求参数等信息生成MD5,或者直接生成UUID来存入,防止并发时多个请求存入的score和value一样导致只存入一个数据。

步骤如下:

  1. 定义时间窗口
  2. 请求到来,丢弃时间窗口之外的数据,ZREMRANGEBYSCORE KEYS[i], -inf, window_start
  3. 判断时间窗口内的请求个数是否达到阈值。ZCARD KEYS[i] 要小于阈值
  4. 如果小于则通过zadd加入,超过则返回不放行

lua脚本:

local window_start = tonumber(ARGV[1])- tonumber(ARGV[2])
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', window_start)
local current_requests = redis.call('ZCARD', KEYS[1])
if current_requests < tonumber(ARGV[3]) then
    redis.call('ZADD', KEYS[1], tonumber(ARGV[1]), ARGV[4])
    return 1
else
    return 0
end

java通过注解+切面实现限流

在java中,我们的需求是对资源可以进行多种规则的限流。注解可以定义不同类型的限流,如:全局限流,根据IP限流,根据用户限流。对每种类型的限流可以在一个注解中定义多个限流规则。

整体效果如下:

@RateLimiter(rules = {@RateLimitRule(time = 50,count = 100),@RateLimitRule(time = 20,count = 10)}, type = LimitType.IP)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值