In this tutorial, you will learn how to configure fallback in Microservices in case a service fails.
With fallback, when one service is down or busy, then the traffic would be redirected to a backup service.
The architecture we would be using for the demo is shown below:
Let’s now try to understand the various parts of this architecture. Then we would demonstrate how it works using Spring Boot, Feign Client and Hystrix.
Step by step tutorial on building microservices with Spring Boot and Eureka.
Angular UI: This is just a user interface application built in AngularJS that serves up html page. The app runs on port 4200 and displays a list of products in HTML page.
Video Tutorial on building the Angular UI here.
ProductWeb: This is a web application that has the api for the list of products. It is build with Spring Boot and runs on Port 8081. This service contains a REST controller and a service(Product Service) that exposes the available endpoints to the Angular UI. app.
Feign Client/Hystrix System: This is actually where the magi happens. So I would try to clearly explain this section. In practice, this system is built as part of ProductWeb but technically is a separate system.
This section is made up of three components:
- Product Service Proxy: This is an interface that extends the Product Service(already explained here). Requests coming from the Product Web are proxied (routed) through the Product Service Proxy to the Product Server 1. This is the normal operation. This service is a Client and therefore annotated with the @FeignClient annotation and Product Server 2 url. If something goes wrong (maybe it could not reach Product Server 1), then it has to report to(or fallback to) Product Alternate Server Component. Therefore, a fallback component is provided as well. See the code for the class below
@FeignClient( name="product-proxy", url = "http://localhost:8080", fallback = ProductAlternateServerComponent.class) public interface ProductServiceProxy extends ProductService { }
- Product Alternate Service Proxy: This is also exactly like the Product Service Proxy. However, the Alternate Service proxy proxies into Product Server 2. This service is a Feign Client and therefore annotated with the @FeignClient annotation. See code below
@FeignClient( name = "product-alternate-proxy", url = "http://localhost:8079") public interface ProductAlternateServiceProxy extends ProductService { }
- Product Alternate Server Component: This is like the cordinator of the two proxies. It is a component class that implements the ProductServiceProxy. It is responsible for receiving notification when the main proxy could not connect. So it automatically fires up an alternate proxy. So this service is annotated by the @EnableFeignClients annotation. It contains methods that make calls using the methods available in the Alternate proxy. See part of code below
@EnableFeignClients(basePackageClasses = ProductAlternateServiceProxy.class) @ComponentScan(basePackageClasses = ProductAlternateServiceProxy.class) @Component public class ProductAlternateServerComponent implements ProductServiceProxy { //Codes... }
Product Server 1: This is a complete microservice containing all the necessary data. It connects to a MongoDB database (How to Setup MongoDB with Spring Boot) and retrieves data through a repository. It also performs other CRUD operations. All these are exposed via a REST Controller.
Product Server 2: This is similar to Product Server 1 and has everything Server 1 has. However, under normal operation, the Product Server 2 is redundant. It only triggers when there is failure of Product Server 1.
End to End Data Flow of Fallback Handling
Below is the end to end flow of data from the Angular UI app to the servers.
- User access the html page in the Angular UI and request some resource(list of product)
- The request routes to the ProductWeb microservice
- The ProductWeb sends the request through the Feign Client’s ProductServiceProxy to ProductServer 1 (normal operation)
- If the ProductServer 1 is up and running, then the request is received by the server, executed and response is sent back to the user
- However, if the ProductServer 1 is down or busy, then the request falls back to the ProductAlternateProxy Component
- The ProductAlternateProxy Compoent then routes the request to ProductServer 2 through the Feign Client’s ProductAlternateServiceProxy.
- The ProductAlternateProxyComponent handles the routing between ProductServiceProxy and ProductAlternateServiceProxy.
See links to the Complete Files on Github
- Angular UI App: https://github.com/KindsonTheGenius/ProductUI
- Product Web: https://github.com/KindsonTheGenius/ProductWeb
- Product Server: https://github.com/KindsonTheGenius/ProductServer
Dear Kindson:
I am new to springboot and I wanted to understand thing that are happening inside of browser and in the server. Do you have browser and server interaction diagram for application flow below?
Thank you in advance
Hello KS, this is an interesting question. I don’t have this diagram for now. When my schedule free up a bit I would try to create one. Keep learning and feel free to reach me anytime if you have challenges.