How to Implement Rate Limiting in Microservices with Resilience4j
This article explains why rate limiting is essential for resilient microservices, demonstrates a simple e‑commerce order flow, and provides step‑by‑step code examples using Resilience4j to restrict request throughput, handle overload, and automatically retry failed calls.
Introduction
Microservices are essentially distributed architectures; when using a distributed system, any unpredictable issue—such as network, service, or middleware availability problems—can occur. A problem in one system may directly affect another system's usage or performance. Therefore, during system design we must ensure our own resilience while avoiding cascading failures to downstream services.
Rate Limiting Pattern
In a microservice architecture with multiple services (A, B, C, D), a service (A) may depend on another service (B), which in turn may depend on C, and so on.
The diagram below shows two services, A and B, where B performs heavy business calculations and external calls, resulting in a maximum request capacity smaller than the concurrent requests from A.
When service A receives many requests, B cannot handle the load and may crash.
Service B protects itself by rejecting requests it cannot process, ensuring normal operation.
Rate limiting restricts the number of requests processed within a specified time window, helping improve service availability.
Sample Program
Architecture Diagram
The diagram illustrates a simple e‑commerce order flow.
User logs in and browses products (inventory module)
Deduct product inventory (inventory module)
Create product order (order module)
product‑service calls order‑service to place an order.
Code Implementation
<code>├── ratelimiter-demo
├── order-service # Order service (port 8070)
└── product-service # Product inventory service (port 8050)
</code>Dependency note: Hystrix is outdated; this demo uses Resilience4j circuit breaker.
<code><dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.6.1</version>
</dependency>
</code>Retry policy: at most 5 requests are allowed within a 10‑second window.
<code>resilience4j.ratelimiter:
instances:
createOrder:
limitForPeriod: 5 # maximum number of calls
limitRefreshPeriod: 10s # time window
</code>Consumer interface (product‑service, port 8050)
<code>/**
* User clicks purchase
*/
@SneakyThrows
@GetMapping("/order")
public String buy() {
// Simulate calling order service to create an order
orderService.createOrder().get();
return "success";
}
</code>Remote call class wrapped with @RateLimiter
<code>/**
* Create order
* name: specifies the rate limiter configuration name
* fallbackMethod: method to call when rate limit is exceeded
*/
@RateLimiter(name = "createOrder", fallbackMethod = "getError")
public CompletableFuture<String> createOrder() {
return CompletableFuture.supplyAsync(() ->
restTemplate.getForEntity("http://localhost:8070/createOrder", String.class).getBody()
);
}
public CompletableFuture<String> getError(Throwable error) {
log.warn("Order creation failed {}", error.getMessage());
throw new RuntimeException("Order creation failed");
}
</code>Provider service (order‑service, port 8070)
<code>@RestController
public class PayController {
@SneakyThrows
@GetMapping("/createOrder")
public String createOrder() {
return "创建订单服务";
}
}
</code>Running the Test
10 concurrent threads request the product service; the policy allows only 5 requests per 10 seconds.
Order service log shows the first request triggers a RateLimiter exception; the client automatically retries, causing a second call.
<code>2020-12-07 15:53:46.698 WARN 52265 --- [nio-8050-exec-6] c.example.product.service.OrderService : 创建订单失败了 RateLimiter 'createOrder' does not permit further calls
... exception log ...
</code>Source code: https://github.com/lltx/microservices-pattern
Reference material and some images: https://www.vinsguru.com
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.