The RequestRateLimiter
GatewayFilter
Factory
The RequestRateLimiter
GatewayFilter
factory uses a RateLimiter
implementation to determine if the current request is allowed to proceed. If it is not, a status of HTTP 429 - Too Many Requests
(by default) is returned.
This filter takes an optional keyResolver
parameter and parameters specific to the rate limiter (described later in this section).
keyResolver
is a bean that implements the KeyResolver
interface.
In configuration, reference the bean by name using SpEL.
#{@myKeyResolver}
is a SpEL expression that references a bean named myKeyResolver
.
The following listing shows the KeyResolver
interface:
public interface KeyResolver {
Mono<String> resolve(ServerWebExchange exchange);
}
The KeyResolver
interface lets pluggable strategies derive the key for limiting requests.
In future milestone releases, there will be some KeyResolver
implementations.
The default implementation of KeyResolver
is the PrincipalNameKeyResolver
, which retrieves the Principal
from the ServerWebExchange
and calls Principal.getName()
.
By default, if the KeyResolver
does not find a key, requests are denied.
You can adjust this behavior by setting the spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key
(true
or false
) and spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code
properties.
The Example 2. application.properties
# INVALID SHORTCUT CONFIGURATION spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver} |
The Redis RateLimiter
The Redis implementation is based off of work done at Stripe.
It requires the use of the spring-boot-starter-data-redis-reactive
Spring Boot starter.
The algorithm used is the Token Bucket Algorithm.
The redis-rate-limiter.replenishRate
is how many requests per second you want a user to be allowed to do, without any dropped requests.
This is the rate at which the token bucket is filled.
The redis-rate-limiter.burstCapacity
is the maximum number of requests a user is allowed to do in a single second.
This is the number of tokens the token bucket can hold.
Setting this value to zero blocks all requests.
A steady rate is accomplished by setting the same value in replenishRate
and burstCapacity
.
Temporary bursts can be allowed by setting burstCapacity
higher than replenishRate
.
In this case, the rate limiter needs to be allowed some time between bursts (according to replenishRate
), as two consecutive bursts will result in dropped requests (HTTP 429 - Too Many Requests
).
The following listing configures a redis-rate-limiter
:
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
The following example configures a KeyResolver in Java:
@Bean
KeyResolver userKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}
This defines a request rate limit of 10 per user. A burst of 20 is allowed, but, in the next second, only 10 requests are available.
The KeyResolver
is a simple one that gets the user
request parameter (note that this is not recommended for production).
You can also define a rate limiter as a bean that implements the RateLimiter
interface.
In configuration, you can reference the bean by name using SpEL.
#{@myRateLimiter}
is a SpEL expression that references a bean with named myRateLimiter
.
The following listing defines a rate limiter that uses the KeyResolver
defined in the previous listing:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
rate-limiter: "#{@myRateLimiter}"
key-resolver: "#{@userKeyResolver}"