1

I want to optimize the resilience4j rate limiter to allow

  • a rate limiting per user
  • a staggered rate limiting (like 1 call/second but only 30 calls/minute but only 1000 calls/hour).

This should protect a resource from DOS attacks but not limit the "normal" user.

Is it possible to reach this with the default resilience4j decorators or can I write my own decorator?

(Or is my approach completely wrong to counteract a DOS attack in this way?)

Datz
  • 3,156
  • 3
  • 22
  • 50

1 Answers1

1

You might use .andThen(secondDecorator) like a fixed issue does mention

protected <T> Function<Publisher<T>, Publisher<T>> decorateWithCircuitBreakerForSpecificEndpoint() {
    final CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
        .failureRateThreshold(100)
        .recordFailure(throwable -> throwable instanceof RuntimeException)
        .ringBufferSizeInClosedState(10)
        .ringBufferSizeInHalfOpenState(10)
        .waitDurationInOpenState(Duration.ofSeconds(5_000))
        .build();
    final CircuitBreaker circuitBreaker = this.circuitBreakerRegistry.circuitBreaker("test1", circuitBreakerConfig);
    return CircuitBreakerOperator.<T>of(circuitBreaker).andThen(decorateWithCircuitBreakerForSpecificHost());
}

protected <T> Function<Publisher<T>, Publisher<T>> decorateWithCircuitBreakerForSpecificHost() {
    final CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
        .failureRateThreshold(10)
        .recordFailure(throwable -> throwable instanceof RuntimeException)
        .ringBufferSizeInClosedState(5)
        .ringBufferSizeInHalfOpenState(5)
        .waitDurationInOpenState(Duration.ofSeconds(5_000))
        .build();
    final CircuitBreaker circuitBreaker = this.circuitBreakerRegistry.circuitBreaker("test2", circuitBreakerConfig);
    return CircuitBreakerOperator.<T>of(circuitBreaker);
}
IQbrod
  • 2,060
  • 1
  • 6
  • 28
  • Thanks, I didn't know about `andThen()` - must try it for rate limiting – Datz Oct 26 '22 at 10:35
  • @datz keep us in touch, that might be helpful for others – IQbrod Oct 26 '22 at 15:01
  • We decided to protect the system by using a Web Application Firewall (WAF). Nevertheless, I think that limiting the rate by users in this way is not possible. – Datz Oct 27 '22 at 06:16
  • 1
    I don't understand why, resilience4j does match your use case. Here's an [answer](https://stackoverflow.com/a/69395768/11825162) limiting per apikey (which is the same as limiting per user considering user is logged in and has a unique id) – IQbrod Oct 28 '22 at 08:05
  • just because I didn't know about the LimiterManager! – Datz Oct 28 '22 at 08:28