分布式限流

一、核心原理

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

分布式限流核心原理:

  • ① 所有请求共享同一个计数器 / 令牌桶
  • ② 计数必须原子化(多线程 / 多机器不冲突)
  • ③ 统一存储: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) 统一控制,不要每个服务自己实现。

相关推荐
woniu_buhui_fei14 小时前
Redis实现分布式限流
数据库·redis·分布式
D4c-lovetrain14 小时前
Jenkins 实战:Java 项目全自动打包、镜像构建、K8s 集群部署(完整CI/CD方案)
java·kubernetes·jenkins
摇滚侠14 小时前
阿里云镜像站 CentOS Tomcat Maven 等镜像资源
java·阿里云·centos
身如柳絮随风扬14 小时前
ArrayList vs LinkedList:底层原理、性能对决与扩容机制全解析
java
超梦dasgg14 小时前
归并排序 Java 实现(递归 + 非递归)
java·算法·排序算法
我是一颗柠檬14 小时前
【JDK8新特性】JDK8实战与面试高频考点汇总Day12
java·开发语言·后端·面试·职场和发展
疯狂成瘾者14 小时前
常见的优化查询速度方法
java
YOU OU14 小时前
Spring事务和事务传播机制
java·数据库·spring
Chase_______14 小时前
【Java基础】5 / 2 为什么等于 2?整数除法、取余和 floorMod 一次讲清
java·开发语言