In this write up, we are going to look at what micro services are really all about, understanding the concept and understanding the architecture.
Before the invention of web applications, computer programmers will write their code, compile and install on the client computer. Clients consume software that has been preinstalled on their machines. Most software’s are still being deployed today in this way.
The coming of the Internet brought about web applications where computer programmer will develop their software and install on a remote machine (Server) and client will access these application via the network.
Today we have huge amount of applications being deployed in this way. With the raising demands of an application running on the server, issues like speed of processing users request, flexibility of infrastructure update, cost management and application feature updates is becoming a problem.
As always with my write up, I like to approach a concept with an example. In this write up, we are going to work though how micro services is being used to address some of these issues using a basic online retail application. We are not going to develop this application but we will design the architecture of this application so as to understand the concepts in this write up.
Lets assume that in our online retail application, we have different modules like
Yes! there are many other modules involve in an online retail application but we will just assume these above modules to explain the concepts.
A typical user in our application will signup, add his/her credit card details, browse product online and make purchase and the product will then be shipped to his/her address.
A reasonable design without micro services
In the above design, The whole application is hosted on a single server with all the modules logically separated and work together to achieve the business of online retail.
The application modules most time share the same database.
There is nothing wrong with this design. This is a monolith architecture and it is being used by many big companies today.
Despite having a logically modular architecture, the application is compiled and deployed as a single application (monolith). A monolith application come with a lot of advantages:
However, as the monolith start getting big, it become difficult to make changes due to the huge complexity of the application. If there is a bug from a change, it may affect other modules. Also, it becomes difficult to leverage the advantages of other programing languages on different module of the application.
During deployment of a monolith, you must deploy the entire application and this may results to some down time of the application. Also, continuous deployment becomes very difficult due to the complexity in deployment given that all the modules and possible dependencies may need to be deployed every time.
Monolithic applications can also be difficult to scale when different modules have conflicting resource requirements.
The popularity of the micro-service architecture is mainly because it addresses some of the challenges faced by monolith application.
A reasonable design with micro services
This is the idea of splitting your application into a set of smaller, interconnected services instead of building a single monolithic application.
The first thing to do is how to separate each module into a micro service. It is important to note that not every module is necessary suppose to be a micro service. But in this our example we will consider each module as a micro-service.
Each micro-service is a small application that has its own hexagonal architecture consisting of business logic along with it own layers and related dependencies like database, caching etc. Some micro-services would expose a RESTful API, RPC or message-based API and services relate to each other by consuming API produced by other service.
There is usually a front API service, API Gateway, that get to route every request to the different micro-service. A micro-service may also be a front API for multiple other services beneath it.
The design above is not yet complete, it may solve some problems of the monolithic design but it also introduce another concern about scaling.
What if Product Management Service is scaled horizontally with about FOUR instances, how will the API Gateway know which instance to call?
This problem can be solve by introducing a load balancer.
A load balancer has the ROUTE (URL) to every instance for each of the micro-service and when a request for maybe to browse product catalog, reaches the API Gateway, the API gateway reaches to the load balancer to get the route for the next available instance of the product management service.
From this, it would make a perfect sense for the API Gateway to be the load balancer for our Design. It may not necessary be a Load balancer, but however must API Gateway serve as a load balancer.
What if a micro-service e.g Product Management with THREE instances has ONE of the instance down, how will the API Gateway know so as to prevent routing to a broken service instance?
This problem can be solve by having another service that constantly check for the status of all instances of the application micro-services. This service is call Discovery Service.
The Discovery Service does Service Discovery or Service Registry of all the micro-service instances.
Each time a new instance of a micro-service is lunched, it registered it route with the Discovery service alongside a check status route. The Discovery service basically keeps a logbook of what route is UP or DOWN for every micro-service instance by constantly calling the check status route.
Now, when the API Gateway/Load balancer wishes to make call to any of the micro-services instance, it look on the Discovery Service’s logbook for available service route.
Here is the complete design of the Online Retail Application using Micro Service Architecture.
Now, With our complete micro-service design, let go through and see if it solves all the disadvantages of a monolithic design
Micro Service architecture solves the problem of complexity of making code changes. If some new feature is to be added, it will just be on the particular service and if there is a bug in one of the services, it may not necessary affect the entire application since each service is completely an independent code base.
Each micro-service is deployed independently of one another and so, if the is a dependency for a service it deployment will not affect all the other services. For example if you are suppose to restart the web server while deploying a particular service, its deployment down time may not affect other part of the application.
Scaling can be very cost effective. Given that scaling a micro-service is independent, of the other service, you can scale different services depending on their demand. For example, if the Product Management service gets more hit than the Payment Management Service. You can allocate more instances on Product Management and less instances on Payment Management Service. This help in allocating resources only where it is needed.
Some of the draw backs of micro services include