In my project, I have to ratelimit underlying service call, implemented a solution using resilliance4j, while doing performance testing with more number of users / load it is not rate limiting the underlying service call as expected. Sometimes, it triggering RequestNotPermitted but not most of the times and not limiting underlying calls as configured.
I am using Spring WebClient to make service call
My sample implementation looks like,
Class Test {
@Autowired
private ServiceRepository serviceRepository;
private List<Dto> testRateLimit(List<Object> list) {
return Flux.fromIterable(list).flatMap(o -> serviceRepository.underlyingServiceCall(o))
.doOnSucces(
//do something
)
.doOnError(
//log error message
)
.onErrorResume(
//do something
).collectList().block();
}
}
Class ServiceRepository {
@Autowired
private WebClient webClient;
RateLimiter rateLimiter = RateLimiter.of("test",
RateLimiterConfig
.custom()
.limitForPeriod(10)
.limitRefreshPeriod(Duration.ofSeconds(1))
.timeoutDuration(Duration.ofSeconds(0)).build());
@TimeLimiter(name= "Test")
@CircuitBreaker(name= "Test")
private Mono<Dto> underlyingServiceCall(Object o) {
return webClient
.post()
.uri("xyz")
.bodyValue(o)
.doOnNext(a -> {
// log message
})
.transform(RateLimiter.of(rateLimiter))
}
}
I have to allow only 10 calls per second to the underlying service,
For example,
thread 1 executing the method testRateLimit() with 6 object
thread 2 executing the method testRateLimit() with 8 object then the ratelimiter should restrict processing 4 objects from thread2.
To know whether it is working, I am using splunk query based on the log message which is printed inside doOnNext() in webclient implementation.
Your input will be helpful.