Introduction – Microservices explained
Probably “Microservices” is the most discussed terminology within today’s technical diaspora. Even though there is no concrete definition of microservices, still we perceive it as an architectural pattern where a large software application is supposed to be a collection of independently deploy-able services. This pattern has gained huge popularity in last couple of years and organizations like Amazon, Netflix, Uber etc. have already adopted it. In near future “Microservices Architecture Pattern” will become the default style for creating enterprise applications. It can also be described as a way of thinking.
The following are the properties that commonly describe microservices:
- Independent processes
- Communicate over API
- High degree of autonomy
- Small and focused on doing one thing well
- Defined over a bounded context
- Small autonomous services that work together
- Technology agnostic and platform agnostic
- Polyglot, supports multiple technologies
- Minimum governance
In general, the microservice architectural style is an approach to construct a single application as a cluster of multiple tiny services where each service runs in its own process and communicates over HTTP based API or message queues. Each service is supposed to fulfill one single business capability and is independently deployable. The deployment mechanism must be fully automated and the culture of DevOps must be properly conceived. Each service can be written in a separate programming language and can store data in different type of database (Relational or NoSQL). Centralized governance of these services should not be required ideally.
The three most important characteristics of this architecture pattern are:
Comparison with Monolithic Architecture
Microservices are best described when they are compared to monoliths. Traditional enterprise applications are generally comprised of three discrete tiers: the User Interface layer, the service layer and the database layer. The client side user interface generally consists of HTML and java scripts and the database is mostly a relational one and SQL based. The service layer acts as a middle-ware. Its captures the HTTP based request from UI layer or client, processes the required domain logic, interacts with the downstream database system and returns the result to the client tier. This server side component is the monolith one, a single deployable unit. It is a single logical executable and any change in the system would require a fresh build and deployment of the entire server side application. In this architecture pattern scaling is done by replicating the same monolithic application on multiple servers behind a load balancer and it requires greater resource allocation.
But nowadays, when many enterprises are moving their applications to the cloud and frequent changes in the business requirements result in frequent deployment cycles, this monolithic pattern is becoming more and more frustrating and losing popularity sharply.
The following points distinctly summarizes the pain points of monolithic architectural pattern.
- Lack of flexibility – Monolithic applications do not support multiple technologies. It is nearly impossible to adopt new technology or framework as the entire set of functionalities have to build on homogeneous platform based on a single technology or framework. So it’s really hard to innovate.
- Lack of reliability – Monolithic applications lack reliability at a large extent as malfunctioning of a single service can let the entire application down.
- Lack of scalability – Monolithic application has to be scaled as a whole as a single application . In that case different scaling requirements can lead to a horribly tough situation. If one service of a monolith requires more memory and another one needs more CPU then scaling of such an application would leave us helpless. Moreover it is required to rebuild and redeploy the entire application, in order to update a part of it.
- Hinders continuous development approach – In today’s world of Agile development many features of the applications cannot be built and deployed simultaneously. Features have to be added one after another and each time the entire application has to be deployed.
These shortcomings in the monolithic paradigm have led to the microservice architectural style where applications are built as cluster of several services which are independently deployable and horizontally scalable. Each service adheres to a single bounded context. Different services can be written in different programming languages by different teams as well
Principles of Microservices
So if we concentrate our focus on the principles of microservices, the following points can be highlighted.
Modeled around business domain
In monolithic approach an application is always split into parts based on technology stack namely UI team, server side team and the database team. But in microservices paradigm splitting of services happens based on business capability. One particular micro-service caters to one particular business capability completely. It encompasses the entire technology stack required to build the mentioned business capability which includes UI, server side, database technology and interaction with any external API. This leads to the culture of having cross functional teams, each team dedicated to one particular business service and having the entire knowledge and skills for building that service completely staring from Designing, Project management, User Interface, Business layer technology to database technology as well.
Modularization by services
We the developers are always in favor of software that is componentized to several independent modules. Even though there is no hard and fast definition of a software module, we by our common perception consider a software component to be an independent piece of software that can be easy pluggable to an existing application. This independent component must have a separate life-cycle and must be independently upgradeable and replaceable without hampering the functionality of the main application. In microservices architecture pattern, this componentization is achieved by breaking down the software to services defined by explicit interface and separated by well defined business boundary.
Hide Implementation details
In traditional SOA architecture style often services communicate with each other over an ESB layer. Ideally this ESB layer is supposed to be very thin, devoid of any business logic and used only for messaging, transformation by applying business rules and orchestration. But the real life scenario is mostly far from this assumption as the middleware developers end up with writing substantial amount of business logic in this layer making it unnecessarily thick and tightly coupled. This leads to leakage of implementation details in the orchestration layer which is not a proper design pattern.
On the contrary, in the microservices pattern the inter-service communication happens over very light weight message bus like RabbitMQ or over simple REST based calls. It makes the channel thin and devoid of any business intelligence. This infrastructure is typically dumb as it provides only the messaging service. The term “Smart Endpoints and Dumb Pipes” are best to describe the interaction between microservices. The entire business intelligence lies within the endpoints that produce and consume the message.
Decentralization of all the things starting from technology choice to database choice to deployment schedule is another flavor of microservices architecture pattern. Decentralization of governance allows teams to choose different technology for building different components. Choosing the right tool for the right job is a common practice in this pattern as there is to centralized governance. Teams are free to use reusable tools created by some other team to address the similar kind of problem. Decentralization of database storage mechanism allows each microservice manage its own database. Instead of having a single relational database like a monolithic application generally has, microservices are allowed to have completely different database systems. This is commonly referred as Polyglot Persistence.
Culture of Automation
We can say that DevOps and Automation are the two wives of microservices architecture pattern. Without proper infrastructure automation with distributed CI/CD pipeline system deployments of microservices over clouds are impossible to achieve. Being dynamic in nature, the complexity associated with the deployment of microservices are far different compared to the monolith. Strong DevOps skill is a mandatory requirement in this paradigm of architecture. A monolith application can be deployed on a single application server and managed servers associated with it. But in microservices pattern each service requires its own application servers cluster for proper load balancing.
Isolation of Failure
Microservices are not reliable by default. Cascading failures can create fatal disruption to the entire set-up. In this architecture style innumerable services run on different platforms and communicate with each other. Dependency of one service over one or multiple other services is very common in our experience. Any service call could fail due to the unavailability of the producer service and the client or the consumer service has to handle it as delicately as possible. Since services can fail at any moment, it’s of severe importance to build a highly effective fault tolerance system which would allow to detect the failures as quickly as possible and provide remedial and, if possible, automatically restore service. The handling of failure is known as Circuit Breakers in this world.
Constant monitoring and real time effective surveillance is another requirement in this architectural world. It includes application health check both at architecture level and business level as well. Constant analytics of these data (how many requests are getting fired per second, or how many requests are hitting the database on a particular span of time) helps the development team to get a real time glimpse of the entire system and assert for unforeseen situation. This is achieved by establishing variety of sophisticated logging and monitoring system which provides aggregation of logging and aggregation of different system statistics, displays the same on charts and diagrams in a dashboard that reflects the application health status at any particular instant of time.
Advantages of Microservices
Briefly following are the advantages of microservices.
- Independently deployable
- Easily testable
- Independently scalable
- Much more secure
- Enable regression model
- Adapt technology more easily
- Allows to release business functionality much quicker
Disadvantages of Microservices
Microservices architecture pattern is not the solution to every problem in real life. It also comes with its own cons. The following are notable.
- Many options
- It is time consuming to break a monolith to microservices
- Testing is more complex specially regression
- Monitoring is more complex
- Associated risk of cascading failure
- Distributed systems are legitimately harder
A real life use case of breaking monolith to microservices
Here we will discuss the case study of a popular app based radio cab service provider, who initially started their taxi operations in a single city. Their application was purely monolithic and layered. But as time progressed the company spread their operations in more and more cities in different geographies. Moreover they started adding different features to their application. As a natural consequence the monolith became fat, hefty, and non-maintainable with a lot of scalability issues. To cater the frequent changes in business features and rapid expansion of their business the provider decided to break their monolith into highly scalable and independent microservices.
Let’s consider on the monolith first. The image is depicted above. It is a typical hexagonal architecture pattern where the core business functionalities reside within the hexagon. Each side of the hexagon corresponds to a adapter through which the functionalities interact with the external world through APIs. Here we find 4 different types of adapters.
- The Database adapter connects the application to the single relational database
- The Browser or Web adapter through which the functionalities are exposed as web application for users
- The REST API adapter is used by the Driver and the passengers from their mobiles
- The other adapters cater to billing, payments and notification services
So, the main thing to be noticed here is all the functionalities and services provided by the application such as passenger management, billing information, notification features, payment services, trip management and driver management were contained within a single monolith which makes it tightly couples and tedious to scale.
Transitioning from a Monolithic to a Microservices based Architecture
Later on the service provider decided to break the monolith to multiple microservices. Each microservice can be considered as a mini‑application that has its own hexagonal architecture consisting of business logic along with various adapters. Few of them might expose APIs to be consumed by other microservices or by any external client. Other microservices might implement a web UI. At run-time, each instance would run in a self contained container. The architecture is depicted below.
The following diagram shows the database architecture for the example application.
One of the most important decisions you can make when designing a new software solution is the architecture you choose. In this article, we will explored the benefits of using a microservices architecture. A microservices architecture is a style of software architecture that structures an application as a collection of loosely coupled services that communicate with each other using message-based protocols.
There are a ton of benefits to using a microservices architecture for your next project. First, it’s great for scalability and for keeping your code modular. But it’s also a perfect solution for writing your code in a way that’s more resilient to change. Microservices architecture is also a good solution if you want to have a flexible and agile development team. It’s also easier to make changes to your system when everything is broken up into smaller chunks.
A microservices architecture is an approach to designing a system or application as a suite of small services that work together to achieve a single goal. It is an alternative to a system built as a single large application or monolithic system. Microservices are, in a word, the future of application architecture. They’re the backbone of a new generation of applications which require a high degree of resilience and scalability in order to meet the needs of the consumer.
In this blog post, I have explore the fundamentals of microservice architectures and why they’re the perfect solution to meet the needs of your end users.
In our next article in this series, I will discuss Spring Cloud, a sub-project of Spring Framework, and how we can use Spring Cloud to implement a scalable Microservices based system. Till then, enjoy learning Microservices.