In earlier days, monolithic architecture was used everywhere. It was a single application which facilitate the all functions in the system. It was simple and easy to organize early. But when the systems get complex, developers had to face a lot of issues.
Lets take this taxi app(like Uber) architecture. It has a central application that handles every feature of the system.
In this example, these modules are resident inside one application. So the code base must be huge and consume more resources. These modules are coupled tight.
Imagine you are going to add a feature or change the code. Then you need to test the code and all integration testing so on. Even you need to understand the whole flow of the code before modifying it. This happens because it is tightly coupled with other components. A small change in one component can affect another component's flow.
Usually, trip tracking might have more traffic than billing components. Since all of these are inside one application you need to scale up the whole application. But it is not efficient.
Whole features should be implemented using one technology or framework. But technologies are getting changed, updated frequently. With a monolithic approach, it is hard to upgrade frequently.
In early, most of the systems were developed in monolithic architecture. But with time, developers understood it would be easy if the application is more modular.
So they started developing separate applications with separate technologies, and infrastructures. With that, they could write and test modules separately and even scale.
The services were running on the same network and services communicated internally over the network.
But still, it had some kind of coupling between services.
Then developers start thinking to develop more modular components than in service oriented approach.
Micro-services architecture is an extension from service oriented architecture. A module in micro-services can be modified, tested, deployed without affecting other modules.
Micro-services has hexagonal architecture. Which means a module can be plugged in anywhere, any application. They are more granular.
Each micro-service is a mini application that has its own hexagonal architecture consisting of business logic along with various adapters. Sometimes micro-services would expose and API that is consumed by other micro-services or by the application's clients.
At runtime, each instance is often a cloud virtual machine(VM) or a Docker container.
Lets take the same example we got earlier.
Since the micro services are separated applications, we can modify, and add new features without affecting other applications. We don't need to test other applications. But in product testing it might be overhead.
We can scale up selected micro services at demand. So it does not need much resources for unnecessary applications.
Since we can run multiple instances, we can have much availability. Imagine one instance fails due to some reason. But we have another instance up and running. So with this approach we can have better availability and reliability with this approach.
- With this hexagonal architecture, we can use this component in any applications. These micro-services are more oriented on their task. So a new developer can easily adapt to working on a micro service, since he does not need to know about the whole application idea.
Micro-services architectures are distributed systems with decentralized data management. They do not rely on a unifying schema in a central database.
Micro-services architecture take a heterogeneous approach to operating systems, programming languages, data stores and tools.
Do one thing well
Each micro-service component it designed for a set of capabilities and focuses on a specific domain.
You build it, you run it
The team responsible for building a service is also responsible for operating and maintaining it in production.
They hide the details of their complexity from other components.
Different components in a micro-services architecture can be changed, upgraded or replaced independently without affecting the functioning of other components.
Enables the continuous delivery and deployment of large, complex applications and enables to organize the development effort around multiple, auto teams.
- Better test-ability - services are smaller and faster to test
- Better deploy-ability - services can be deployed independently
- Flexible scaling
- Easy deployment
- Technological freedom
- Reusable code
Developers must deal with the additional complexity of creating a distributed application.
- Developer tools/ IDEs are oriented on building monolithic applications.
- Developers must implement the inter service communication mechanism.
- Implementing distributed transactions is difficult.
- Implementing use cases that span multiple services requires careful coordination between the teams.
- Testing is more difficult
- More deployment complexity.
- In production, there is also the operational complexity of deploying and managing a system comprised of many different service types.
- Increased memory consumption.
Introduction to microservices by Ashish Pandey