Resilience4j | Circuit breaker basics & runtime behavior/state changes | Simple example for beginners

In this article we will look at very simple basic example of Resilience4j circuit breaker & look at runtime behavior & all possible state changes of circuit breaker. Here is the maven dependency for resilience4j-circuitbreaker required for this example.

Circuit Breaker Concept

If service call is giving errors more than expected, stop calling that service for certain wait time & take some alternate recovery path during that time. After wait is over, check if service stopped giving error with limited calls & then resume calling service else wait again. This avoids unnecessary network traffic & also unwanted load on service when its already known to throw errors that time.

Example in this article

Circuit Breaker Configurations: (Default) Check status of last 100 calls. If 50% of those 100 calls ended up in exception, then open circuit i.e. block any further calls for next 60 seconds. After 60 seconds over, allow 10 calls to check if calls succeeding. If success then close circuit back i.e. allow calls or again open it & wait 60 seconds.

  • Create mock service which returns success for first 100 calls & then throws BadProcessingException for rest of the calls.
  • We will call this service with circuit breaker default configurations as give above.
  • For test purpose we will make 1 call per second.
  • We will observe how circuit breaker behaves in success & failures. As calls are happening per second, we can also see how wait duration works after open state.

Mock service

This is a mock service as explained above.



Circuit Breaker in action

  • External service call is wrapped / decorated with circuit breaker.
  • Circuit breaker has default configurations as documented in code.
  • Code will call external service 1 per second.
  • Code will print circuit breaker metrics after each call so that we can observer behavior in output.



Output (Circuit breaker state changes in action)

We can see behavior of circuit breaker in output. Several logs in output have been skipped to give better visual understanding.

Key behavior to look for in output

  • Exception from service (Call counter = 100)
    • External service starts throwing BadProcessingException as per mock service.
    • Failed call count in circuit breaker will start increasing.
    • Ring buffer (size 100) is also full, so failure rate will start calculating.
  • Ring buffer slides (Call counter = 101)
    • Since success/failure count is stored in ring/circular buffer of size 100, from 101 onwards, success count starts going down & failure count goes up i.e. total counted calls (success + failure) will always be 100 i.e. same as “sliding window size” or “ring buffer size”
  • Failure rate threshold cross, hence CLOSED to OPEN (Call counter = 149)
    • Current failure rate reaches 50%. “Default failure rate threshold” configured is also 50% so circuit breaker opens.
  • Calls to service stops (Call counter = 150)
    • Here onwards all calls to external service will receive io.github.resilience4j.circuitbreaker.CallNotPermittedException
    • Actual call to external service won’t happen.
  • Wait time in open is over, hence OPEN to HALF_OPEN (Call counter = 209)
    • 60 seconds are over since circuit breaker is open.
    • “Wait time in open state” configured is also 60 seconds, so circuit breaker goes to HALF_OPEN state. Calls to external service start happening.
  • Still failing, hence HALF_OPEN to OPEN (Call counter = 218)
    • 10 calls made since HALF_OPEN state & “Permitted calls in half open state” are configured to  10.
    • So now again failure rate is calculated which comes to 100% which is more than failure rate threshold i.e. 50%. So circuit breaker opens again.
  • Wait time in open is over, hence OPEN to HALF_OPEN (Call counter = 278)
    • 60 seconds are over since last circuit breaker is open.
    • “Wait time in open state” is also 60 seconds, so circuit breaker goes to HALF_OPEN state. Calls to external service start happening.
  • Now calls successful, hence HALF_OPEN to CLOSED (Call counter = 287)
    • 10 calls made since HALF_OPEN state & “Permitted calls in half open state” are configured to 10.
    • So now again failure rate is calculated which comes to 0% since all calls are successful now. So circuit breaker closes & calls to external service starts happening.





Further reading

Resilience4j | Expose Circuit Breaker Metrics to JMX using Micrometer | Simple example

Resilience4j Complete Tutorial | Basics with runtime behavior | Simple examples for beginners

Leave a Reply

Your email address will not be published. Required fields are marked *