在高并发系统中,限流(Rate Limiting) 是保护后端服务不被突发流量打垮的关键手段。但传统的“一刀切”限流策略往往无法满足业务多样性需求——比如,我们希望 普通用户每秒最多调用 1 次接口,而 VIP 用户可以调用 5 次。

本文将带你使用 Redisson + Redis 实现一种灵活、高效的令牌桶限流方案,并通过动态令牌消耗量实现用户级别的差异化限流策略。

🔧 技术选型:为什么选择 Redisson?

  • Redisson 是 Redis 的 Java 客户端,提供了丰富的分布式对象(如 RRateLimiter

  • 其内置的 分布式限流器 基于 Redis 的原子操作,天然支持集群环境

  • 配置简单,性能优异,适合生产环境

📦 第一步:添加依赖

pom.xml中引入 Redisson:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>4.1.0</version>
</dependency>

💡 建议使用较新版本(如 3.23+ 或 4.x),以获得更好的稳定性和功能支持。

⚙️ 第二步:配置 Redisson 客户端

通过 Spring Boot 自动装配 Redis 配置,创建 RedissonClient Bean:

@Configuration
@ConfigurationProperties(prefix = "spring.data.redis")
@Data
public class RedissonConfig {

    private Integer database;
    private String host;
    private int port;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
                .setDatabase(database)
                .setAddress("redis://" + host + ":" + port);
        return Redisson.create(config);
    }
}

🚦 第三步:实现差异化限流逻辑

核心思想:不同用户类型消耗不同数量的令牌

@Service
public class RateLimitService {

    @Resource
    private RedissonClient redissonClient;

    /**
     * 执行限流检查
     *
     * @param key      限流键(如 userId 或 ip)
     * @param tokens   当前请求需要消耗的令牌数
     */
    public void doRateLimit(String key, int tokens) {
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
        // 设置规则:整体限流,每秒生成 5 个令牌,窗口 1 秒
        rateLimiter.trySetRate(RateType.OVERALL, 5, 1, RateIntervalUnit.SECONDS);

        boolean acquired = rateLimiter.tryAcquire(tokens);
        if (!acquired) {
            throw new BusinessException(ErrorCode.TOO_MANY_REQUEST);
        }
    }
}

🎯 第四步:业务层调用示例

在 Controller 或 Service 中根据用户身份决定令牌消耗量:

// 普通用户:一次请求消耗 5 个令牌 → 每秒最多 1 次
rateLimitService.doRateLimit("user:123", 5);

// VIP 用户:一次请求消耗 1 个令牌 → 每秒最多 5 次
rateLimitService.doRateLimit("vip:456", 1);

✨ 效果:

  • 普通用户:1 秒内第 2 次请求 → 被拒绝

  • VIP 用户:1 秒内可连续成功调用 5 次

💡 优势与扩展

特性

说明

灵活配额

可按用户等级、IP、接口等维度设置不同 tokens

自动过期

Redisson 的限流器会自动清理空闲 key,避免内存泄漏

高并发安全

基于 Redis 原子操作,无竞态条件

易于监控

可通过 Redis 查看限流 key 的剩余令牌数

🔜 进阶:结合 Spring AOP + 注解,实现 @RateLimit(tokens = 3) 声明式限流!

✅ 总结

通过 Redisson 的 RRateLimiter,我们轻松实现了基于用户角色的精细化限流策略。这种方案不仅代码简洁、性能高效,还能灵活应对各种业务场景——无论是防刷、防爬,还是会员特权控制,都能游刃有余。

限流不是限制用户,而是保障服务的公平与稳定

📚 参考资料