This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Cloud Gateway 4.1.5! |
RateLimiter Filter
The RateLimiter Filter use Bucket4j 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.
Please review Bucket4j Concepts prior to reading this documentation.
The algorithm used by Bucket4j is the Token Bucket Algorithm.
The filter takes a keyResolver
parameter and other Bucket4j configuration parameters. The key resolver is a java.util.Function<ServerRequest, String>
. This allows the user to extract any information out of the request to use as a key in the configured Bucket4j distribution mechanism. A common key would be the Principal
retrieved from the ServerRequest
.
By default, if the key resolver does not find a key, requests are denied with the FORBIDDEN
status.
Currently, the only way to configure key resolvers is through the Java DSL and not through external properties. |
Bucket4j Distributed Configuration
A bean of type io.github.bucket4j.distributed.proxy.AsyncProxyManager
. To do this, use the ProxyManager.asAsync()
method.
import com.github.benmanes.caffeine.cache.Caffeine;
import io.github.bucket4j.caffeine.CaffeineProxyManager;
@Configuration
class RateLimiterConfiguration {
@Bean
public AsyncProxyManager<String> caffeineProxyManager() {
Caffeine<String, RemoteBucketState> builder = (Caffeine) Caffeine.newBuilder().maximumSize(100);
return new CaffeineProxyManager<>(builder, Duration.ofMinutes(1)).asAsync();
}
}
The above configures an AsyncProxyManager
using Caffeine
, a local in-memory cache, useful for testing.
Configuring Buckets
By default, the Bucket is configured using a configured capacity
and period
. Capacity is how many tokens the bucket has. The period is a java.util.Duration
that defines how long for the tokens available in the bucket to be regenerated.
Other configuration items are the statusCode
returned when the request is denied. By default it is 429, TO_MANY_REQUESTS. The tokens
item defines how many tokens are used for each request and defaults to 1. The headerName
item is the name of the header that contains the number of remaining tokens, this defaults to X-RateLimit-Remaining
. The timeout
option defines a Duration
for the distributed bucket to return an answer and is not set by default.
The following is an example of configuring a route with rate limiting:
import static org.springframework.cloud.gateway.server.mvc.filter.Bucket4jFilterFunctions.rateLimit;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsRateLimited() {
return route("rate_limited_route")
.GET("/api/**", http("https://example.org"))
.filter(rateLimit(c -> c.setCapacity(100)
.setPeriod(Duration.ofMinutes(1))
.setKeyResolver(request -> request.servletRequest().getUserPrincipal().getName())))
.build();
}
}
This configures the rate limiting with a bucket capacity of 100 tokens per minute. The key resolver gets the principle name from the Servlet request.