Introduction
Rate limiting is a crucial aspect of API security and performance. It prevents abuse, ensures fair usage, and protects backend services from being overwhelmed by excessive requests. In this tutorial, we will implement a Redis-based rate limiter in a Spring Boot Gateway server.
Dependency
Add the following dependency to the pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
Configuring redis rate limiter
Add the following two beans:
@Bean
public RedisRateLimiter redisRateLimiter() {
return new RedisRateLimiter(1, 1, 1);
}
@Bean
KeyResolver userKeySolver() {
return exchange -> Mono.justOrEmpty(exchange.getRequest().getHeaders().getFirst("user"))
.defaultIfEmpty("anonymous");
}
Add the requestRateLimiter:
@Bean
public RouteLocator eshopAppRouterConfig(RouteLocatorBuilder routeLocatorBuilder) {
return routeLocatorBuilder.routes().route(p -> p.path("/eshop/productservice/**")
.filters(f -> f.rewritePath("/eshop/productservice/(?<segment>.*)", "/${segment}").requestRateLimiter(
config -> config.setRateLimiter(redisRateLimiter()).setKeyResolver(userKeySolver())))
.uri("lb://PRODUCTSERVICE")).build();
}
The redisRateLimiter bean defines a Redis-based rate limiter.
The parameters (1, 1, 1) correspond to:
- Replenish Rate:
1→ Number of requests added per second. - Burst Capacity:
1→ Maximum number of requests allowed in a burst. - Requested Tokens:
1→ Number of tokens required for each request.
The userKeySolver defines a KeyResolver that extracts a unique key for rate limiting. It reads the "user" header from the HTTP request. If the header is missing, it defaults to "anonymous". The KeyResolver determines which key to use for rate limiting. This key is used in Redis to track API requests per user.
Add the following under spring:
data:
redis:
connect-timeout: 2s
host: localhost
port: 6379
timeout: 1s
Starting the redis
Use the following docker command to run the redis:
docker run -p 6379:6379 --name eazyredis -d redis
Testing the code
You can use Apache bench to send multiple requests. If a request exceeds the limit, it is rejected with an HTTP 429 (Too Many Requests).
To Read
Read about the BulkHead Pattern and it’s implementation using Resilience4j
