【手撕系列】Java限流算法终篇:分布式限流实现与实战!(建议收藏)

🔥 本文是限流算法系列的终篇,将带你深入了解分布式环境下的限流实现。从Redis到集群,从原理到实战,全方位掌握分布式限流技术。

📚 博主匠心之作,强推专栏

沉淀

一、Redis分布式限流

1.1 Redis+Lua固定窗口限流

说到分布式限流,最常见的需求是:限制某个接口每秒只能处理N个请求。这种场景下,固定窗口限流就是一个不错的选择。

为什么选择Redis+Lua这个组合呢?主要考虑两点:

  • Redis的性能足够好,每秒可以处理数万次请求
  • Lua脚本能保证原子性,避免并发问题

让我们先看看具体实现:

-- 固定窗口限流脚本
local key = KEYS[1]           -- 限流KEY
local limit = tonumber(ARGV[1])    -- 限流大小
local current = tonumber(redis.call('get', key) or "0")

-- 检查是否超过限制
if current + 1 > limit then
    return 0
else
    -- 计数器+1,并设置1秒过期
    redis.call("INCRBY", key, 1)
    redis.call("EXPIRE", key, 1)
    return 1
end

这个脚本的逻辑很简单:用Redis的key记录1秒内的请求数,超过限制就返回失败。通过EXPIRE命令自动清理过期计数器,实现滑动窗口的效果。

接下来看看Java端如何调用这个脚本:

/**
 * Redis限流器
 * 使用Redis+Lua实现分布式限流
 */
public class RedisRateLimiter {
   
   
    private final StringRedisTemplate redisTemplate;
    
    /** 限流Lua脚本,保证原子性 */
    private final String luaScript;
    
    /**
     * 构造函数
     * @param redisTemplate Redis操作模板
     */
    public RedisRateLimiter(StringRedisTemplate redisTemplate) {
   
   
        this.redisTemplate = redisTemplate;
        // 加载Lua脚本
        this.luaScript = loadLimitScript();
    }
    
    /**
     * 尝试通过限流检查
     * @param key 限流标识,如:order:create
     * @param limit 限流阈值,如:每秒1000次
     * @return true:通过限流;false:被限流
     */
    public boolean isAllowed(String key, int limit) {
   
   
        try {
   
   
            // 封装Lua脚本参数
            List<String> keys = Collections.singletonList(key);
            
            // 执行Lua脚本
            // 返回1表示通过限流,0表示被限流
            return redisTemplate.execute(
                new DefaultRedisScript<>(luaScript, Long.class),
                keys,
                String.valueOf(limit)
            ) == 1;
        } catch (Exception e) {
   
   
            log.error
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值