Microservices is an Architectural style in which large, complex software applications are composed of one or more smaller services.
These smaller services are called Microservices which are independently deployed and consist of a single business function.
These are the four main considerations to work with, towards this architecture:
- Loosely Coupled: This means that each service can operate independently without coordination with other services.
- Small and Focused: The goal of Microservices is simplicity so that it can be written and maintained by the team effortlessly.
- Language Neutral: The Microservice must be Language Neutral, for example some of the Microservices can be faster on Java because of extensive library, whereas some can be on Python for quicker deployment.
- Bounded context: Each Microservice doesn’t need to understand the implementation of other Microservices.
Below is the pictorial depiction of a banking application with multiple Microservices, each Microservice performs only one task and can have different language and implementation, to best deliver business result.
“When you’re ready as an engineering organization.”
The most important step on the path towards the approach to Microservices, is domain understanding. If you can’t understand it, or if you are still in the process of figuring it out, then Microservices can do more harm than good. However, if you have a deep understanding and you know about the boundaries and dependencies, you can start making the right moves towards Microservices architecture.
WHAT’S IN IT FOR ME?
Applications designed using the Microservices architecture are basically applications composed of small autonomous services. These services are loosely coupled and only communicate through APIs. They are less complex and smaller as they are only responsible for only a single business function. Basically, instead of building a big single monolithic code base for the entire application, the application is made up of multiple services which have their own code base. This allows the companies to develop, deploy and update parts of the application in a faster and more Agile way, which in turn helps them to respond to the changing market in very minimal time. With that, becoming a Responsive Enterprise.
Time to market and Agility being the main drivers for using Microservices, results in the following advantages:
- Independent deployments: With monolithic applications, fast reliable deployments can be problematic. For example, if we want to introduce a small new feature, add a new field to a user profile or perform just a small bug fix, the entire application needs to be built and deployed again as a single application. Also, not to forget about the testing effort that makes sure that the new changes are not breaking any part of the application. In Microservices-based architecture, we need to update and deploy only the Microservice to which the new feature or bug fix belongs. Therfore, this reduces the testing effort.
- Independently Scalable: Applications are commonly scaled up by increasing the number of machines i.e. instances which comes with load balancing among these instances. In case of monolithic applications, if one feature needs to be scaled, we end up scaling the entire application by adding another instance which means more machines, resulting in higher cost. In case of Microservices-based architecture, if one single service needs be to be scaled, then we can always upgrade the machine on which that service is running, say for example user profile requires a lot of memory, then we can simply deploy it to an instance with higher memory configuration thus optimizing the deployment costs.
- Different Technology stacks and conflicting dependencies: monolithic applications are typically developed in one single technical stack, often on a specific version of a stack. If one component of the service can benefit with the newer version of the stack, they still cannot upgrade the technology stack because the upgrade may not support some other application component. So, it’s always a bit problematic to upgrade the version of technology stack in Monolithic architecture, whereas with a Microservices-based approach, each Microservice can leverage different framework versions, technical stack which allows you to pick the best technology stack for the feature and avoiding version conflicts between features/libraries. For example, a feature named profile service can be implemented in Java, benefitting from elastic search feature, whereas another service i.e. order service can use node.js and a transactional database with consistency and reporting features.
THINGS TO KEEP IN MIND WHEN DEALING WITH MICROSERVICES:
While Microservices-based architecture offers great benefits, it is important keep in mind that the architecture falls under the realm of distributed computing. Distributed computing has been a complex topic and Microservices are no different. These are the following things to keep in mind while starting with Microservices:
- Increased complexity: Due to multiple Microservices in one application, instead of one deployment we will be dealing with deployments of tens or hundreds of services which need to work together seamlessly.
- Network Congestion and Latency: As Microservices communicate via APIs through standard protocols, there may be hundreds of services in an application with request spanning multiple services will impact the overall performance of the application. One more concern overlooked is data serialization and de-serialization, sometimes same data is passed to from one service to another where it is serialized and de-serialized multiple times which can increase the Latency.
- Fault Tolerance: This is one of the characteristics of the Microservices-based architecture, they are fault tolerant even in the event of catastrophic failures. But as there are many Microservices with networks involved, chances of faults increase. We understand that each Microservice is running in its own process then it should not affect another Microservice. Here is an example: say if a Microservice takes too long to respond, exhausting all the threads in the calling service which can cause fatal cascading failure in the entire call chain.