分布式限流

一、核心原理

分布式限流的核心:在集群多台机器上,统一控制总请求速率,而不是每台机器各自限流。

分布式限流核心原理:

  • ① 所有请求共享同一个计数器 / 令牌桶
  • ② 计数必须原子化(多线程 / 多机器不冲突)
  • ③ 统一存储:Redis(最主流)
  • ④ 执行必须高效:用 Lua 脚本保证原子性

一句话总结: Redis + Lua 脚本 = 分布式限流标准方案

二、最常用的 3 种实现方式

1. Redis + Lua(固定窗口限流,最简单通用)

Lua 复制代码
-- key:限流key(如接口名/用户ID)
-- max:最大允许数
-- ttl:时间窗口(秒)
local count = redis.call("incr", KEYS[1])
if count == 1 then
    redis.call("expire", KEYS[1], ARGV[1])
end
if count > tonumber(ARGV[2]) then
    return 0  -- 超过限流,拒绝
end
return 1      -- 放行

原理:

  • 单位时间(如 1 秒)最多允许 N 个请求
  • 用 Redis 做全局计数
  • Lua 脚本保证:判断 + 计数 + 过期 原子执行,无并发问题

优点:实现最简单、性能极高

适用:绝大多数接口限流、网关限流、IP 限流

2. Redis + Lua(令牌桶限流,支持突发流量)

原理:

  • 桶里固定容量令牌
  • 每秒固定放入 N 个令牌
  • 请求拿走一个令牌,没有就拒绝

适用:电商、秒杀、允许瞬时流量突增

3. 成熟框架(不用写代码,直接集成)

如果不想写 Redis+Lua,直接用现成框架:

1) Sentinel(阿里出品,推荐)
  • 原理:默认「滑动窗口」,同时支持令牌桶、漏桶
  • 位置:服务内部(资源层),可在网关、业务接口、方法、热点参数上使用Sentinel。
  • 粒度:细粒度,资源(接口 / 方法)、QPS、并发线程、热点参数、链路 / 关联限流。
  • 目的:服务级精准防护、熔断降级、流量塑形
  • 依赖:单机可独立运行,分布式可结合 Redis/Nacos 等。
2) Spring Cloud Gateway
  • 原理:Redis 存令牌(固定用「令牌桶」),按速率生成,桶有容量,允许一定突发。
  • 位置:网关层(入口),所有请求先到网关。
  • 粒度:粗粒度,按路由 / 接口 / IP / 用户限流。
  • 目的:全局流量削峰、挡大流量、保护整个微服务集群
  • 依赖:必须配合 Redis + Lua 做分布式计数。
Lua 复制代码
--yaml文件
filters:
  - name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10  # 每秒生成10个
      redis-rate-limiter.burstCapacity: 20 # 桶最大20个
3) Redisson
  • Redis 官方推荐的 Java 客户端,轻松实现分布式锁 + 分布式限流 + 高并发可靠性
  • 自带 RRateLimiter
  • 一行代码实现分布式限流
java 复制代码
public boolean tryAccess() {
    // 限流 key
    RRateLimiter rateLimiter = redissonClient.getRateLimiter("limit:api:getOrder");

    // 规则:每秒生成 10 个令牌
    rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);

    // 尝试获取 1 个令牌
    return rateLimiter.tryAcquire(1);
}

三、关键点

  • 为什么必须用 Lua? 避免多机并发导致计数不准,保证原子性。

  • 为什么用 Redis? 高性能、内存操作、集群统一计数。

  • 固定窗口 vs 滑动窗口

    • 固定窗口:简单,但临界值可能突刺
    • 滑动窗口:更平滑,适合严格限流
  • 分布式限流一定放在哪里? 网关层(Gateway/Nginx) 统一控制,不要每个服务自己实现。

相关推荐
Jazz_z1 小时前
通过 Java 实现 Word 转 TXT
java·c#·word
SamDeepThinking1 小时前
为什么我会主动给一个年轻程序员加薪、晋升?
java·后端·程序员
ikun_文1 小时前
Java面向对象编程OOP核心知识
java
宠友信息2 小时前
MySQL 租户数据隔离在即时通讯源码后端中的落地方式
java·数据库·spring boot·redis·websocket·mysql
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第163题】【06_Spring篇】第23题:说说SpringBoot 自动配置原理?
java·自动配置·springboot·spi·条件注解
江湖有缘2 小时前
【保姆级教程】使用Docker Compose一键搭建Picsur私有图床服务
java·docker·容器
一路向北North2 小时前
Spring Security OAuth2.0(18):资源服务测试
java·后端·spring
极光代码工作室3 小时前
基于SpringBoot的订单管理系统
java·springboot·web开发·后端开发
xiaoduzi19913 小时前
ConcurrentHashMap学习
java·学习
折哥的程序人生 · 物流技术专研3 小时前
《Java 100 天进阶之路》第53篇:volatile与JMM(2026版)
java·volatile·内存屏障·可见性·java内存模型·jmm·java100天进阶