Scenario (online bookstore)
You gonna build online bookstore with following features
- Customers can create and maintain their accounts of the store
- Maintain catalog of books
- Maintain inventory of books
- Customers can purchase/order books from the store by making online payments
- Customers can add their reviews for the books
There are several ways to implement this application. One options is a monolithic solution.
In this way whole functionality implemented in a single application. If you use java build the application you can package it as .war file and deploy it under tomcat or any other application server. If you use python, you can use Django kind of MVC framework to develop it.
Following could be an architecture of the monolithic system.
Application consists with following components.
- Customer(manage customers)
- Catalog(manage informations of the books)
- Inventory(manage available books and counts)
- Payment(manage online payments)
- Review(keep review of the books)
- Front end(mobile and web front end)
The important point is, these components are aggregate as a single application with sharing a single database. There some advantages as well as disadvantage of this monolithic solution
Benefits in monolithic
- Easy to develop since IDEs and other development tools are oriented around developing a single application
- Easy to test since you just need to launch the one application
- Easy to deploy since you just have to copy the deployment unit to application server
- Easy to scale since you can run multiple copies of the application behind a load balancer(X axis scaling )
Even though monolithic architecture having these kind of advantages, it causes lot of problems when application size is increasing(this architecture is suitable for relatively simple application not for complex applications)
Challenges in monolithic
Following problems could be occurs when size of the monolithic application is increasing(when application getting complex)
- When codebase getting larger(and complex) its hard to developers to understand and maintain the system. Even for make a simple change it takes lot of time
- When codebase getting large its an overload to IDE. It slows up time and development time which makes less productivity for developers
- Its hard to continuously deliver the application. In order to update one component you have to redeploy the entire application
- Its hard to scale since monolithic applications can only scale on one die-mention (X axis scaling)
- One misbehaving component of a monolithic architecture will bring down the entire system
- With monolithic architecture its difficult to adopt to new technologies(such as programming languages, frameworks). For an example if you develop your application based on JVM language(such as java), you have to stick to JVM languages(such as groovy, scala). You cannot develop your application components with ruby of python
To overcome these types of problems(which are exists in complex/large monolithic application) we can use microservices architecture.
Microservices is an alternative architecture to address the limitation of large/complex monolithic applications. The idea of microservices architecture is to split your application into set of smaller, interconnected services instead of building a single monolithic application.
The idea of decomposing application into small services comes from scale cube.
In here we are doing Y-axis scaling. Unlike X-axis or Z-axis scaling Y-axis scaling splits the application into multiple, different services(according to the functionalities).
Each service is responsible to do one thing and each service has its own database in order to be decoupled from other services. In previously mentioned online bookstore scenario services can be decomposed as below
- Customer service which is responsible to manage customers
- Catalog service which is responsible to maintain book informations
- Inventory service which is responsible to maintain inventory of books
- Payment service which is responsible to manage online paymets
- Review service which is maintaining customer reviews of the books
Following could be the architecture of microservices based system for the online bookstore
These services can be communicate with each other by using either synchronous protocols such as HTTP/REST or asynchronous protocols such as AMQP. For an example when purchase need to be done by a customer, UI can call to inventory service to verify the book is available, if book is available call for payment service in order to do the payment.
Service decomposition #UnixPhilosophy
As mentioned previously application is decomposed into several services according to the functionality. Single service responsible to do only one thing(as same as Single Responsible Principle in OOP). Service decomposition happens according the unix philosophy “Doing one thing well”
Services on the microservices system can be identifies as side effects less services since a service only doing one thing well(according to the unix philosophy)
Consider following unix commands
ls | wc-l
In here “ls” command responsible to list the files in a directory. “wc -l” command count the no of lines in input stream(both of the commands only doing one things). “|” (pipe) pass the input of one command to another. Commands(ls, wc-l) are responsible for accepting or rejecting the input.
This is the same way services on microservices system works. It takes input(via synchronous REST of asynchronous AMQP), do what every operation and return response back. It means “Doing one thing well”
Benefits in microservices
- Since micro services are relatively small and simple, its easy to developers to understand and maintain the code. Simple codebase doesn’t an overload the IDE and improve the productivity of the developer
- Each service can be developed and deployed independently, also its easy deploy services frequently
- Easy to scale the services by combining X-axis and Y-axis scaling
- Its easy to adopt a new technologies and languages. For an instance you can develop one service with java and other with python. Only thing you need to do is expose calling end point to the service(such as REST endpoint)
- It improves fault isolation, when one service is down or crash other services can continue their work normally
Challenges in microservices
Microservices architecture is not a silver bullet. There are lot of challenges and drawbacks on it
- There is a additional complexity of building distributed system.
- IDEs basically focusing on developing monolithic application, its hard to debug and test the applications
- Need to have strong DevOps sills in order to manage/monitor/deploy/redeploy various services
- Additional cost to monitor each and every service
- Additional network overhead when communicating between services
- Additional cost to maintain a service registry. We need to have a registry to keep track with where the service lives (host, port, node name)
To overcome some of these issues there are some patterns introduced in micro services architecture. Two of them are below
- API gateway pattern
- Service discovery pattern
When developing microservices application, you need to consider how clients are interacting with application.
“Consider the scenario where displaying the book information on UI (in web or mobile front end) in previously mentioned online bookstore application”
In here book information page(mobile or web front end) could be display following informations.
- Book information
- Pricing information
- Available no of copies
- Payment information
- Customer reviews
These informations could be exists in different services
- Book informations and pricing informations are on catalog service
- Available no of copies are on inventory service
- Payment methods are on payment service
- Customer reviews are on review service
To display these information client need to interact with multiple services. In this scenario client need to call for 4 services. If client make requests to all of these services it is an additional overhead.
To overcome this overhead we can introduce API gateway service. It provides a single entry point(may be REST endpoint) to all clients. In above scenario the API gateway can provide entry point(REST endpoint api/v1/books/?id=23) to get book information.
By using this entry point clint can directly(via single call to API gateway)get book information instead of calling to different different services. All requests comes to API gateway. API gateway routes requests to the appropriate microservice. When response comes from microservices it aggregate them and response back to the client. Normally API gateway responsible to handle
- Request routing and composition
- Protocol translation(Https to AMQP)
- Load balancing
AS mentioned previously microservices based application contains large no of different different services. Most of the times these services are deployed in cloud environment with virtual machines of containers(example docker).
These services are talking each other(using either synchronous protocols such as HTTP/REST or asynchronous protocols such as AMQP). In order to talk with each other services(as well as clients) should know about each other. If simply says services and clients need to know where the other services live(hosts and posts)
In typical microservices environment(its a distributed environment) the number of services instances and their locations changes dynamically. It means new services are adding frequently, locations of existing services can be changed frequently. So when new service created or location of the service changed there should be a way to rest of the network(services) can automatically find it and start to communication with the new/changed service. This process is called Service Discovery.
To do service discovery we need to have a service registry. Simply a service registry is a phonebook(database) for your microservices which keeps services and their locations(host, port). Each and every service instance register in this registry with their informations(service name, host, port) on service startup. Services deregistered from the service registry when they shutdown.
Clients and other services can query this registry to find available instance of the other services.
Available service register
Following are some available service register which can use as your service registry. Most of them are available as docker images which are can simply up and run as docker containers.
A comprehensive solution to service discovery will have three properties
- A consistent (ideally), highly available service directory
- A mechanism to register services and monitor service health
- A mechanism to lookup and connect to services
Microservices vs SOA
Microservices and SOA sounds like same, but they ARN’T same. Microservices can be identifies as an evolution of SOA concepts that can provide additional benefits to adopting organisations. The benefit of microservices over “traditional” SOA is
- Speed and agility for making changes
- Ability to make changes with less overall cost and less impact on the existing infrastructure
Following are some differences of Microservices and SOA
1. No WS-* in microservices
SOA is based on WS-*(web service specification). Most of the time SOA implements as WSDL based SOAP services. These are heavy weight protocols. But microsrvices application uses simple, lightweight protocols such as REST. The Microservice architecture pattern also rejects other parts of SOA, such as the concept of a “canonical schema”
2. No ESB in microservices
Microservices avoid using ESB, instead they implements ESB-like functionality in the microservices themselves(REST endpoints, AMQP endpoints)
3. Services are smaller
Services in microservice systems are smaller than the services in SOA designs, but most importantly micro services are standalone and are a manifestation of the “Single responsibility principle”.
SOA integrates different monolithic applications via ESB. In microservices one application contains multiple microservices.
“SOA integrates multiple monolithic applications via ESB. In microservices one applications contains multiple services(call microservices)”
4. No governance need in microservices
SOA does not exist if there is no governance. Microservices has a very lightweight orchestration layer where governance is not a mandatory objective
5. Microservices are independently deployerble
Microservices must be independently deployable, whereas SOA services are often implemented in deployment monoliths(different monolithic applications).
Microservices are deployed on VMs or Containers(such as Docker). In microservices the deployment process can be automated by using docker kind of container technologies(easy to deploy than SOA services)
“In microservices one service means one deployment unit. In SOA one deployment unit contains multiple services”
Following is a presentation that I have prepared regarding microservices architecture.