RequestRateLimiter
RequestRateLimiter 网关过滤器工厂使用一个 RateLimiter 实现来确定当前请求是否被允许继续进行。如果不允许,将返回默认情况下的 HTTP 429 - Too Many Requests 状态。
此过滤器接受一个可选的 keyResolver 参数和特定于速率限制器的参数。
KeyResolver
keyResolver 是一个实现 KeyResolver 接口的 bean。在配置中,可以通过 SpEL(Spring Expression Language)引用此 bean。例如:#{@myKeyResolver} 是一个 SpEL 表达式,引用了一个名为 myKeyResolver 的 bean。
以下代码展示了 KeyResolver 接口:
KeyResolver 的默认实现是 PrincipalNameKeyResolver,它从 ServerWebExchange 中获取 Principal 并调用 Principal.getName()。
默认情况下,如果 KeyResolver 找不到键,请求将被拒绝。
可以通过设置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key(true 或 false)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 属性来调整此行为。
Redis RateLimiter
Redis 实现基于 Stripe 的工作,它要求使用 spring-boot-starter-data-redis-reactive。
Redis RateLimiter 使用的算法是令牌桶算法:
redis-rate-limiter.replenishRate 属性定义了每秒允许多少请求(不包括任何被丢弃的请求)。这是令牌桶填充的速率。
redis-rate-limiter.burstCapacity 属性是用户在一秒内允许的最大请求数(不包括任何被丢弃的请求)。这是令牌桶可以容纳的令牌数量。
将此值设置为零会阻止所有请求。
redis-rate-limiter.requestedTokens 属性是每个请求消耗的令牌数。这是每个请求从令牌桶中取走的令牌数,默认为 1。
通过将 replenishRate 和 burstCapacity 设置为同样的值可以实现稳定的速率。
通过将 burstCapacity 设置得高于 replenishRate,可以允许临时的请求突发。在这种情况下,速率限制器需要在两个连续的突发之间留出一些时间(根据 replenishRate),因为连续的两个突发会导致请求被丢弃(HTTP 429 - Too Many Requests)。
将速率限制设置为低于 1 请求/秒的方式是将 replenishRate 设置为所需请求数,将 requestedTokens 设置为以秒为单位的时间跨度,将 burstCapacity 设置为 replenishRate 和 requestedTokens 的乘积。
例如,设置 replenishRate=1,requestedTokens=60,和 burstCapacity=60 将得到一个 1 请求/分钟的限制。
以下配置示例演示了如何配置 redis-rate-limiter:
上述配置定义了每个用户的请求速率限制为 10。允许突发量为 20,但在下一秒中只有 10 个请求可用。
以下示例演示了如何在 Java 中配置一个 KeyResolver:
KeyResolver 是一个简单的实现,它获取用户请求参数。
还可以将速率限制器定义为实现 RateLimiter 接口的 bean。在配置中,可以使用 SpEL 引用该 bean。#{@myRateLimiter} 是一个 SpEL 表达式,引用了名为 myRateLimiter 的 bean。以下示例定义了一个速率限制器,它使用了前面示例中定义的 KeyResolver:
Last updated