跳到主要内容

RequestRateLimiter GatewayFilter 工厂

DeepSeek V3 中英对照 RequestRateLimiter GatewayFilter Factory RequestRateLimiter GatewayFilter Factory

RequestRateLimiter GatewayFilter 工厂使用 RateLimiter 实现来确定当前请求是否允许继续。如果不允许,默认情况下会返回 HTTP 429 - 请求过多 的状态码。

该过滤器接受一个可选的 keyResolver 参数以及特定于速率限制器的参数(在本节后面 部分中描述)。

keyResolver 是一个实现了 KeyResolver 接口的 bean。在配置中,使用 SpEL 通过名称引用该 bean。#{@myKeyResolver} 是一个 SpEL 表达式,它引用了一个名为 myKeyResolver 的 bean。以下清单展示了 KeyResolver 接口:

public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
java

KeyResolver 接口允许可插拔的策略派生用于限制请求的密钥。在未来的里程碑版本中,将会提供一些 KeyResolver 实现。

KeyResolver 的默认实现是 PrincipalNameKeyResolver,它从 ServerWebExchange 中获取 Principal 并调用 Principal.getName()

默认情况下,如果 KeyResolver 没有找到密钥,请求将被拒绝。你可以通过设置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-keytruefalse)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 属性来调整此行为。

备注

RequestRateLimiter 无法使用“快捷”表示法进行配置。以下示例是无效的:

# 无效的快捷配置
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
properties

以下是一个有效的 yaml 参考配置:

spring:
cloud:
gateway:
routes:
- id: limit
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
key-resolver: "#{@userkeyresolver}"
yaml

Redis RateLimiter

Redis 的实现基于 Stripe 的工作成果。它需要使用 spring-boot-starter-data-redis-reactive Spring Boot starter。

所使用的算法是 令牌桶算法

redis-rate-limiter.replenishRate 属性定义了每秒允许的请求数量(不丢弃任何请求)。这是令牌桶填充的速率。

redis-rate-limiter.burstCapacity 属性表示用户在一秒钟内允许的最大请求数(不丢弃任何请求)。这是令牌桶可以持有的令牌数量。将此值设置为零将阻止所有请求。

redis-rate-limiter.requestedTokens 属性表示每次请求消耗的令牌数量。这是从令牌桶中为每个请求提取的令牌数量,默认值为 1

通过将 replenishRateburstCapacity 设置为相同的值,可以实现稳定的速率。通过将 burstCapacity 设置为高于 replenishRate,可以允许临时突发。在这种情况下,速率限制器需要在突发之间留出一些时间(根据 replenishRate),因为连续两次突发会导致请求被丢弃(HTTP 429 - 请求过多)。以下列表配置了一个 redis-rate-limiter

低于 1 请求/秒 的速率限制通过将 replenishRate 设置为所需的请求数,requestedTokens 设置为时间跨度(以秒为单位),并将 burstCapacity 设置为 replenishRaterequestedTokens 的乘积来实现。例如,设置 replenishRate=1requestedTokens=60,以及 burstCapacity=60 将导致限制为 1 请求/分钟

.application.yml

spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
yaml

以下示例在 Java 中配置了一个 KeyResolver

@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
java

这定义了一个每个用户 10 次的请求速率限制。允许突发 20 次请求,但在下一秒,只有 10 次请求可用。KeyResolver 是一个简单的解析器,用于获取 user 请求参数。注意:不建议在生产环境中使用。

你也可以定义一个实现了 RateLimiter 接口的限流器作为 bean。在配置中,你可以使用 SpEL 通过名称引用该 bean。#{@myRateLimiter} 是一个 SpEL 表达式,它引用了一个名为 myRateLimiter 的 bean。以下代码清单定义了一个限流器,它使用了前面代码清单中定义的 KeyResolver

spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"
yaml