Skip to content

Latest commit

 

History

History

circuit-breaker

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Circuit Breaker

The Circuit Breaker is not a new pattern and was not invented together with Microservices principle. Martin Fowler had explained this feature years ago, but either way see more details on our Microservice Architecture foundation. Spring Integration (together with Spring Boot auto-configuration), being a good framework for Microservices development, also provides its own simple RequestHandlerCircuitBreakerAdvice implementation. Yes, there is also Spring Cloud Circuit Breaker project, which provides some primitives and API to configure and call services withing Circuit Breaker callbacks, but we really will concentrate in this demo exactly on Spring Integration native approach since this is really a goal of this project anyway.

So, in two words: Circuit Breaker wraps a service call, breaks the circuit when number of attempts is exhausted, throwing specific "open" exception, then attempts again after halfOpen timeout. All descriptions for this pattern suggest some fallback option to be called in case of open state. Since Spring Integration operates more on the higher level than just method calls, it throws only a specific CircuitBreakerOpenException leaving the freedom to decide what to do up to target project. One of the option is to combine this advice with some other, e.g. with a RequestHandlerRetryAdvice like we do in this demo. The point of using this advice together with a RequestHandlerCircuitBreakerAdvice is to be able to retry automatically and perform a fallback when CircuitBreakerOpenException happens.

This demo is a bit tricky and contains both microservices parts for simplicity to test in isolation. The CircuitBreakerApplication.RemoteServiceConfiguration exposes a REST service based on Spring Integration flow definition which is not started automatically to the RequestHandlerCircuitBreakerAdvice to do its logic during testing. This service just replies with Hello to the value of the name HTTP request parameter. The CircuitBreaker class represents the pattern in action via Spring Integration primitives and configuration. See its setters for more information. For demonstration purposes of the CircuitBreakerOpenException fallback option from the RequestHandlerRetryAdvice, the last one is configured with an AlwaysRetryPolicy and never retry on CircuitBreakerOpenException. The service to call is of course a MessageHandler for HTTP clients. The URL for this client is based on a randomly selected port for Tomcat when JUnit test is started. See rest-service.url property in the resource/application.properties. The @ServiceActivator POJO method on a recoveryChannel is for demonstrating a fallback option of the Circuit Breaker which is initiated by the framework via RequestHandlerRetryAdvice.recoveryCallback. It returns some stub payload and shows how to copy request message headers to preserve at least an important replyChannel header which is needed for initial request-reply call into this application.

The unit test in this project starts an embedded Tomcat with a random port populated into a local.server.port configuration property. During test execution, some DEBUG information is printed from the RetryTemplate and RequestHandlerCircuitBreakerAdvice which may give some understanding in the logic of Circuit Breaker pattern implementation with Spring Integration.