In this blog we will learn about MicroServices Architecture with Spring Cloud Netfix OSS patterns like Intelligent Routing (Zuul), Discovery (Eureka), Circuit Breaker (Hystrix) and Client Side Load Balancing (Ribbon) through Spring Boot autoconfiguration feature.
Before discussing about MicroServices, let’s see the architecture that used to before MicroServices i.e. the Monolithic Architecture – its similar to a big container wherein all the software components of an application are integtated together and tightly packaged.
1. Inflexible – Monolithic applications cannot be built using different technologies
2. Unreliable – Even if one feature of the system does not work, then the entire system does not work
3. Unscalable – Applications cannot be scaled easily since each time the application needs to be updated, the complete system has to be rebuilt
4. Blocks Continous Development – Many features of the applications cannot be built and deployed at the same time
5. Slow Development – Development in monolithic applications take lot of time to be built since each and every feature has to be built one after the other
6. Not Fit For Complex Applications – Features of complex applications have tightly coupled dependencies
1. Decoupling – Services within a system are largely decoupled. So the application as a whole can be easily built, altered, and scaled
2. Componentization – MicroServices are treated as independent components that can be easily replaced and upgraded
3. Business Capabilities – MicroServices are very simple and focus on a single capability
4. Autonomy – Developers and teams can work independently of each other, thus increasing speed
5. Continous Delivery – Allows frequent releases of software, through systematic automation of software creation, testing, and approval
6. Responsibility – MicroServices do not focus on applications as projects. Instead, they treat applications as products for which they are responsible
7. Decentralized Governance – The focus is on using the right tool for the right job. That means there is no standardized pattern or any technology pattern. Developers have the freedom to choose the best useful tools to solve their problems
8. Agility – MicroServices support agile development. Any new feature can be quickly developed and discarded again
1. Separate data store for each MicroService
2. Keep code at a similar level of maturity
3. Separate build for each MicroService
4. Deploy into Containers
5. Treat servers as stateless
Yes, As in 12 Factor App guide lines all the services should be stateless.
Your API should be stateless therefore do not share the session state to the microservices. The recommended approach is to set up a Redis cache to store session data.
Following companies are using MicroServices patterns.
Monolithic Architecture is similar to a big container wherein all the software components of an application are assembled together and tightly packaged.
A Service-Oriented Architecture is a collection of services which communicate with each other. The communication can involve either simple data passing or it could involve two or more services coordinating some activity.
Microservice Architecture is an architectural style that structures an application as a collection of small autonomous services, modeled around a business domain.
In simple words, for object-oriented design we follow the SOLID principles. For microservice design we propose developers follow the IDEALS principles.
Interface segregation tells us that different types of clients (e.g., mobile apps, web apps, CLI programs) should be able to interact with services through the contract that best suits their needs.
Deployability (is on you) acknowledges that in the microservice era, which is also the DevOps era, there are critical design decisions and technology choices developers need to make regarding packaging, deploying and running microservices.
Event-driven suggests that whenever possible we should model our services to be activated by an asynchronous message or event instead of a synchronous call. Availability over consistency reminds us that more often end users value the availability of the system over strong data consistency, and they’re okay with eventual consistency.
Loose-coupling remains an important design concern in the case of microservices, with respect to afferent (incoming) and efferent (outgoing) coupling.
Single responsibility is the idea that enables modeling microservices that are not too large or too slim because they contain the right amount of cohesive functionality. For example each microservice maintains its own database and no other service should access the other service’s database directly.
Single responsibility states that a class should have one and only one reason to change, meaning that a class should have only one job.
Open for extension, closed for modification states that objects or entities should be open for extension but closed for modification.
Liskov substitution reuse via inheritance is dangerous. This means that every subclass or derived class should be substitutable for their base or parent class.
Interface segregation states that a client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use.
Dependency Inversion principle allows for decoupling. It states that Entities must depend on abstractions, not on concretions. It states that the high-level module must not depend on the low-level module, but they should depend on abstractions.
High level MicroServices Architecture using Netflix Components as below
1. Setup new service by using Spring Boot
2. Expose resources via a RestController
3. Consume other MicroService services using RestTemplate
4. Each MicroService has certain specific purpose, and they interact with each other to perform a required functionality.
5. Generally MicroServices are installed in multiple Nodes, and each MicroService may have multiple instances. This is to provide Horizontal scalability.
6. The problem due to this is how one MicroService can detect another MicroService, and the system where it runs, and on which all instances a MicroService runs.
This is termed as Service Registry and Discovery, there is a tool named Eureka for Service Discovery.
A microservice architecture has the following components:
Here is an example without using Eureka component. Problem – How one MicroService can detect another MicroService, and the system where it runs, and on which all instances a MicroService runs?
Eureka Client and Eureka Server(provided by Spring Cloud Netflix OSS) are used for Service Registry & Discovery
“Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers.”
1. Scalable – number of instances on which a MicroService can change, dynamically.
2. Auto-scaling – Number of instances can change auto-scaling, failures, and Software/Hardware upgrades.
The degree to which the elements inside a module belong together is said to be cohesion.
The measure of the strength of the dependencies between components is said to be coupling. A good design is always said to have High Cohesion and Low Coupling.
Below maven dependency needs to be added in Maven File (pom.xml)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
spring.application.name= ${springboot.app.name:eureka-serviceregistry}
server.port = ${server-port:8761}
eureka.instance.hostname= ${springboot.app.name:eureka-serviceregistry}
eureka.client.registerWithEureka= false
eureka.client.fetchRegistry= false
eureka.client.serviceUrl.defaultZone: http://${registry.host:localhost}:${server.port}/eureka/
Below maven dependency needs to be added in Maven File (pom.xml)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Application logs
Developing a number of smaller microservices sounds easy, but the challenges often faced while developing them are as follows.
You may click on below url for Spring Cloud Netflix OSS Load Balancing example
Spring Cloud Netflix OSS + Netflix Eureka + Netflix Ribbon Client Side Load Balancer Example
Kindly let me know in case any issue 🙂