RequestRateLimiterGatewayFilterFactory

一、功能说明

RequestRateLimiterGatewayFilterFactory 是 Spring Cloud Gateway 的流量控制组件,用于实现 API 请求速率限制,核心功能包括:

  1. 限制单位时间内的请求数量(如每秒10次)
  2. 防止服务被突发流量击垮(通过令牌桶算法)
  3. 支持分布式限流(依赖Redis存储)
  4. 可自定义限流维度(按IP、用户ID等)

二、工作原理图

1. 动态流程(时序图)

客户端 API网关 Redis 后端服务 请求 /api/data 1. 调用KeyResolver获取Key(如IP) 2. 返回当前令牌数 3. 扣减令牌 4. 转发请求 返回数据 200 OK 429 Too Many Requests alt [令牌充足] [令牌不足] 客户端 API网关 Redis 后端服务

2. 静态架构(类图)

调用 依赖 读写令牌 RequestRateLimiterGatewayFilterFactory +apply(Config config) RedisRateLimiter -replenishRate: int -burstCapacity: int +isAllowed() <<interface>> KeyResolver +resolve(exchange) RequestRateLimiter Redis


三、示例

1. 配置示例(application.yml)
yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: rate-limit-route
          uri: http://backend-service
          predicates:
            - Path=/api/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter:
                  replenishRate: 10  # 每秒生成10个令牌
                  burstCapacity: 20  # 令牌桶容量
                key-resolver: "#{@ipKeyResolver}"  # 按IP限流
2. 自定义KeyResolver
java 复制代码
@Bean
public KeyResolver ipKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest()
                .getRemoteAddress()
                .getAddress()
                .getHostAddress()
    );
}
3. 触发限流时的响应
http 复制代码
HTTP/1.1 429 Too Many Requests
X-RateLimit-Remaining: 0
X-RateLimit-Retry-After: 1
Content-Type: application/json

{
    "error": "Too many requests",
    "message": "You have exhausted your API request quota"
}

四、对比

在 Spring Cloud Gateway 的限流场景中,@remoteAddrKeyResolver(按 IP 限流) 是最常用且最方便的实现方式,其次是 @pathKeyResolver(按路径限流)。以下是详细对比和推荐场景:


1. 按 IP 限流(@remoteAddrKeyResolver

特点
  • 最常用,适合大多数场景。
  • 直接基于客户端 IP 区分流量来源,无需用户登录或额外参数。
  • 能有效防止单一 IP 的恶意请求或爬虫。
适用场景
  • 匿名访问的 API(如公开接口、登录页)。
  • 防止 DDoS 攻击或刷接口。
  • 简单粗暴的限流需求。
代码示例
java 复制代码
@Bean
public KeyResolver remoteAddrKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
    );
}
优点
  • 实现简单,无需业务逻辑。
  • 对客户端无侵入性(不依赖 Cookie/Token)。
缺点
  • 如果用户使用 NAT 或代理(如公司出口 IP 相同),会误伤正常用户。

2. 按路径限流(@pathKeyResolver

特点
  • 根据请求的 URL 路径区分限流规则。
  • 适合不同 API 接口需要不同限流策略的场景。
适用场景
  • 核心接口(如 /payment/**)需要严格限流,非核心接口(如 /public/**)放宽限制。
  • 需要针对不同路径设置不同 replenishRateburstCapacity
代码示例
java 复制代码
@Bean
public KeyResolver pathKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getPath().toString()
    );
}
优点
  • 灵活性高,可精细化控制不同接口的流量。
  • 不依赖用户身份信息。
缺点
  • 如果同一 IP 频繁请求不同路径,可能绕过限流。

3. 按用户限流(@userKeyResolver

特点
  • 基于用户身份(如用户 ID 或 Token)限流。
  • 适合需要区分用户权限或订阅等级的场景。
适用场景
  • 付费用户和免费用户的 API 调用限制不同。
  • 防止单个用户滥用接口(如频繁提交订单)。
代码示例
java 复制代码
@Bean
public KeyResolver userKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getHeaders().getFirst("Authorization") // 从 Header 取 Token
        // 或 exchange.getRequest().getQueryParams().getFirst("userId") // 从 Query 参数取用户 ID
    );
}
优点
  • 精准控制每个用户的请求量。
  • 适合多租户或 SaaS 系统。
缺点
  • 需要用户已登录或携带身份信息。
  • 实现复杂(需解析 Token 或 Session)。

推荐优先级

  1. @remoteAddrKeyResolver(IP 限流)

    • 推荐指数:★★★★★
    • 适合 80% 的场景,尤其是公开 API。
  2. @pathKeyResolver(路径限流)

    • 推荐指数:★★★★☆
    • 适合需要区分接口重要性的场景。
  3. @userKeyResolver(用户限流)

    • 推荐指数:★★★☆☆
    • 仅限需要用户身份识别的业务(如订单提交)。

最终建议

  • 默认选择 IP 限流:简单、通用,能覆盖大多数恶意请求场景。
  • 结合路径限流 :如果不同接口的 QPS 需求差异大(如 /login 严格限流,/public/news 不限流)。
  • 谨慎使用用户限流:除非业务明确需要(如 VIP 用户特权)。
配置示例(IP + 路径组合限流)
yaml 复制代码
filters:
  - name: RequestRateLimiter
    args:
      redis-rate-limiter.replenishRate: 10
      redis-rate-limiter.burstCapacity: 20
      key-resolver: "#{@ipAndPathKeyResolver}"  # 自定义组合 Key
java 复制代码
@Bean
public KeyResolver ipAndPathKeyResolver() {
    return exchange -> Mono.just(
        exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() 
        + ":" 
        + exchange.getRequest().getPath()
    );
}

五、关键机制解析

组件 作用
RedisRateLimiter 基于令牌桶算法实现限流,依赖Redis存储计数
KeyResolver 定义限流维度(如IP、用户ID、API路径等)
replenishRate 令牌填充速率(如10=每秒10个请求)
burstCapacity 突发流量容量(允许短时间内超过replenishRate的最大值)

六、应用场景

  1. 防御CC攻击:限制单个IP的疯狂刷接口行为
  2. API分级管控:为VIP用户分配更高的请求配额
  3. 服务降级:在系统高负载时主动限流保核心功能

如果需要更复杂的限流策略(如滑动窗口、漏桶算法),可以自定义实现 RateLimiter 接口。

相关推荐
追风筝的人er5 天前
企业管理系统如何实现自定义首页与千人千面?RuoYi Office 给出了完整方案
vue.js·spring boot·spring cloud
坐吃山猪5 天前
OpenClaw04_Gateway常见问题
网络·gateway·openclaw
三水不滴6 天前
利用SpringCloud Gateway 重试 + 降级解决第三方接口频繁超时问题,提升性能
经验分享·笔记·后端·spring·spring cloud·gateway
知识即是力量ol6 天前
微服务架构:从入门到进阶完全指南
java·spring cloud·微服务·nacos·架构·gateway·feign
Java水解6 天前
【Spring Cloud】优雅实现远程调用-OpenFeign
后端·spring cloud
Remember_9936 天前
SpringCloud:Nacos注册中心
java·开发语言·后端·算法·spring·spring cloud·list
j200103226 天前
Gateway—— 高级流量路由
gateway·k8s
J_liaty7 天前
Spring Cloud 微服务面试高频题
spring cloud·微服务·面试
笨蛋不要掉眼泪7 天前
Spring Cloud Gateway 核心篇:深入解析过滤器(Filter)机制与实战
java·服务器·网络·后端·微服务·gateway
笨蛋不要掉眼泪7 天前
Spring Cloud Gateway 扩展:全局跨域配置
java·分布式·微服务·架构·gateway