You have applied the Microservice architecture. Services sometimes collaborate when handling requests. When one service synchronously invokes another there is always the possibility that the other service is unavailable or is exhibiting such high latency it is essentially unusable. Precious resources such as threads might be consumed in the caller while waiting for the other service to respond. This might lead to resource exhaustion, which would make the calling service unable to handle other requests. The failure of one service can potentially cascade to other services throughout the application.
How to prevent a network or service failure from cascading to other services?
A service client should invoke a remote service via a proxy that functions in a similar fashion to an electrical circuit breaker. When the number of consecutive failures crosses a threshold, the circuit breaker trips, and for the duration of a timeout period all attempts to invoke the remote service will fail immediately. After the timeout expires the circuit breaker allows a limited number of test requests to pass through. If those requests succeed the circuit breaker resumes normal operation. Otherwise, if there is a failure the timeout period begins again.
RegistrationServiceProxy
from the Microservices Example application is an example of a component, which is written in Scala, that uses a circuit breaker to handle failures when invoking a remote service.
@Component
class RegistrationServiceProxy @Autowired()(restTemplate: RestTemplate) extends RegistrationService {
@Value("${user_registration_url}")
var userRegistrationUrl: String = _
@HystrixCommand(commandProperties=Array(new HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="800")))
override def registerUser(emailAddress: String, password: String): Either[RegistrationError, String] = {
try {
val response = restTemplate.postForEntity(userRegistrationUrl,
RegistrationBackendRequest(emailAddress, password),
classOf[RegistrationBackendResponse])
response.getStatusCode match {
case HttpStatus.OK =>
Right(response.getBody.id)
}
} catch {
case e: HttpClientErrorException if e.getStatusCode == HttpStatus.CONFLICT =>
Left(DuplicateRegistrationError)
}
}
}
The @HystrixCommand
arranges for calls to registerUser()
to be executed using a circuit breaker.
The circuit breaker functionality is enabled using the @EnableCircuitBreaker
annotation on the UserRegistrationConfiguration
class.
@EnableCircuitBreaker
class UserRegistrationConfiguration {
This pattern has the following benefits:
This pattern has the following issues:
Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns.
Chris helps organizations improve agility and competitiveness through better software architecture. Learn more about his consulting engagements, and training workshops.
Chris teaches comprehensive workshops for architects and developers that will enable your organization use microservices effectively.
Avoid the pitfalls of adopting microservices and learn essential topics, such as service decomposition and design and how to refactor a monolith to microservices.
Learn moreChris offers numerous other resources for learning the microservice architecture.
Want to see an example? Check out Chris Richardson's example applications. See code
Got a specific microservice architecture-related question? For example:
Consider signing up for a two hour, highly focussed, consulting session.
My virtual bootcamp, distributed data patterns in a microservice architecture, is now open for enrollment!
It covers the key distributed data management patterns including Saga, API Composition, and CQRS.
It consists of video lectures, code labs, and a weekly ask-me-anything video conference repeated in multiple timezones.
The regular price is $395/person but use coupon KQAWEXBH to sign up for $120 (valid until November 21st, 2023). There are deeper discounts for buying multiple seats.
Take a look at my Manning LiveProject that teaches you how to develop a service template and microservice chassis.
Engage Chris to create a microservices adoption roadmap and help you define your microservice architecture,
Use the Eventuate.io platform to tackle distributed data management challenges in your microservices architecture.
Eventuate is Chris's latest startup. It makes it easy to use the Saga pattern to manage transactions and the CQRS pattern to implement queries.
Engage Chris to conduct an architectural assessment.
Note: tagging is work-in-process
Microservices adoption · ancient lore · anti-patterns · application api · application architecture · architecting · architecture · architecture documentation · assemblage · beer · books · containers · dark energy and dark matter · deployment · design-time coupling · developer experience · development · devops · docker · eventuate platform · generative AI · glossary · health · hexagonal architecture · implementing commands · implementing queries · inter-service communication · kubernetes · loose coupling · microservice architecture · microservice chassis · microservices adoption · microservicesio updates · modular monolith · multi-architecture docker images · observability · pattern · refactoring to microservices · resilience · sagas · security · service api · service architecture · service collaboration · service design · service discovery · service granularity · service template · software delivery metrics · success triangle · tacos · team topologies · transaction management · transactional messaging
Application architecture patterns
Decomposition
Refactoring to microservicesnew
Data management
Transactional messaging
Testing
Deployment patterns
Cross cutting concerns
Communication style
External API
Service discovery
Reliability
Security
Observability
UI patterns