
Resilience4j at a Glance
Scope of this article is applications based on microservice architecture.
Let me begin with a question, what is most important non-functional requirement from any application? Undoubtedly the answer of this question will be ‘Robustness’. This means applications must behave reasonable with respect to adverse scenarios. Against all adverse scenarios application needs to take either corrective action or redirect to reasonable action or application flow. It is very much required to understand about those adverse scenarios.
- Out of all one or more than one microservice is broken or out of order.
- Need to manage user traffic by fixing number of requests in specific time.
- Need to manage user traffic by fixing specific number of concurrent requests.
There is no dispute on need of above functionality in application to achieve robustness and resiliency in working of application. At some extent Hystrix from Netflix could resolve the issue but not all. Also, Spring Cloud Hystrix project is deprecated. So, under the umbrella of ‘Spring Cloud Circuit Breaker’ Resilience4j is introduced.
Now let us consider above mentioned scenarios in detail and how Resilience4j maintains resiliency.
1. Out of all one or more than one microservice is broken or out of order,
To understand let us consider below implementation of microservices,



In all favorable conditions, nothing to worry but what if any of microservice fails or does not behave as per expected functionality? For time being let us consider below negative scenario,



As per above diagram, Microservice MS2 is non-operational . In flow, microservice MS-1 will not be able to get expected response from MS-2 and expected functionality remains unfulfilled. resilience4j-circuitbreaker will help you to handle such scenarios.
So below are the steps you need to manage resiliency in Springboot,
a) Include dependency in maven similar to below,



b) Setting property value in application.properties file
If you want to call fallback method if failure rate is 60% or more,



more properties values can be set as per need of application behavior.
c) Writing fallback method,



2. Need to manage user traffic by fixing number of requests in specific time,
There are scenarios when we need to restrict number of requests within some specific time. One of the use cases we can consider here which is of provisioning of DB connection. If we want to provision only 100 connections pers second and for next connection after 100th connection application needs to wait for 5 second, below implementation will help to achieve this purpose,
a) Include dependency in maven similar to below,



b) Setting property value in application.properties file,
Below values will ensure that service MS1 will only allow 100 requests in 5 seconds,



c) Writing annotation on REST method,



Above implementation will put a cap of 100 request in 5 seconds. This approach will help to prevent against,
- Web/data scaping.
- Brute force attacks.
- DoS(Denial-of-Service) and DDoS (Distributed Denial-of-Service) attacks.
3. Need to manage user traffic by fixing specific number of concurrent requests,
This is nothing but implementation of bulkhead design pattern. This implementation will be required when we want to distribute concurrent requests evenly among multiple but same microservice. This means if we are anticipating 1000 concurrent request for particular functionality and we have 4 instances of microservice for that functionality. In such scenarios we need to distribute 1000 concurrent requests among 4 available instances.
Below implementation will consider only 25 concurrent requests per instance.
a) Include dependency in maven similar to below,



b) Setting property value in application.properties file
Below value will ensure that service MS1 will only allow 25 concurrent requests,



c) Required annotation for REST method to achieve this will be like below,



So, this is tolerant of failure. We can define or restrict number of request as per capacity of local resources to operate within tolerance limit. This will restrict failure by passively transferring responsibility to other microservices.
Nice blog Abhijna, for the cases that you mentioned, could you also specify
1. If the MS2 is not responding and the circuit breaker kicks in the requests go to the fallback mechanism, how and when does the circuit close again? What happens to the requests which have gone to the fallback mechanism in the meantime
2 &3. Similarly for these scenarios what happens when the number of requests exceed 100 and 25 concurrent users. Are those dropped?
Hi Vikas,
It’s really encouraging when someone like you put such comments and motivates to explore more.
1) Here property ‘waitDurationInOpenState’ plays role to make circuit OPEN to HALF-OPEN state. This means circuit will remain OPEN for specified duration and then moves to HALF-STATE. Once circuit is HALF-OPEN, request will be thrown to unhealthy service to verify health of service.
To decide service is healthy or not ‘ringBufferSizeInHalfOpenState’ property can help to understand same. So, if value of ‘ringBufferSizeInHalfOpenState’ is 5, circuit will not pick OPEN state.
2) Case 2 : RateLimiter rejects the call which are after 100th call in 5 seconds.
Case 3 : It depends on selection of implementation. If we have picked ‘Semaphore’ , request will be rejected if microservices are already handling 25 requests. And, if we have considered ‘FixedThreadPoolBulkhead’, new request will wait till microservice would have room to accommodate them.
We can have fallback method for case 3 & 3 as well to handle negative scenario.
I hope, above explanations helped you to resolve your queries.
Intention of this blog was just to provide glimpse of resilience4j and so I haven’t used any complicated terms and scenario in it.
I may come up with detailed blog in future.