Microservice Overview

A brief overview of Microservices
 
The evolution
Microservices is the new buzz word but it is often misunderstood a lot. It is becoming the defacto application development architecture style. But before talking about microservices, we need to look back in the past and see how it evolved over a period of time. I started as a mainframe Cobol programmer. In those days, we used to write the driver or the main Cobol program which in turn would call programs and those programs used to call more programs. The called programs were either statically or dynamically called in the calling program. The entire set of programs used to be compiled through mainframe compile and then link edit jobs. If the programs were statically called, any change would mean to compile and link edit the entire set of programs and redeploy. A similar approach existed in the java world as well where the entire application is deployed as an EAR file or a WAR file. This single binary deployment was decomposed into data access, business process and presentation layer which also known as N-tier architecture. The layers allowed separation of concerns but the application still used to be deployed as a single monolith. Any new change or enhancement would take days to do impact analysis, testing and finally deployment into production. The coupling of code in monoliths used to make it difficult to do an impact analysis as changes were not localized but spread across the applications. Then we saw a shift towards SOA architecture which broke the applications into modules but then it was also not flawless. It was supposed to be a thin at the aggregation layer but in reality it got heavy with the transformations and the logic that went inside it. It created another level of coupling between internal and external components of the system. Then arrived microservices. The concepts are similar to SOA and I like to think it is more of an evolution of SOA.
 
So, what is a microservice?
Microservice is not a new concept, infact many of the microservices concepts are similar to SOA architectural patterns. Microservices are about decomposing a complex system into more manageable, smaller units of work that can be developed and deployed independently. It follows the long practiced approach of solving a complex problem by breaking it down into multiple smaller problems.
 
Let us now understand the core concepts and components of a microservice. 
Services are at the core of a microservices based architecture. Now, there are no hard and fast rules on the sizing of microservices. They should neither be too fine grained which will make it difficult to manage nor they should be too coarse grained which will require them to have cross domain operation. Making them too fine grained will increase the latency in service calls. Services should be built around the domain and not on a particular data object or a business object. The domain specific CRUD operations should be exposed by the services. It may so happen that a single service is serving multiple business processes and data objects based on the use case. The concept will be clearer if we relate our understanding of a class in the OOP paradigm. A class is developed to work on one specific type of object and it provides various operations to do activities on that object type. Microservices similarly operate on a single domain. There should not be any cross domain operations within a service. Defining that domain boundary, therefore, becomes extremely important in a microservices based development. We must understand that the definition will not be perfect from day one. It will be perfected in an iterative manner over a period of time.
 
Communications between services are recommended to be over HTTP using ReST based services. The beauty of this communication approach is that it hides the complexity of implementation of the services. It also allows developers to pick up any language that supports ReSTful services thus driving development agility. The ReST based communication is protocol-aware and promotes heterogeneous interoperability which means that the services are bound to a protocol (HTTP in this case) and communicates in a heterogeneous environment using this protocol. In addition to communication, there is also the need of collaboration among services to perform a certain business process. The question is whether that collaboration needs to be synchronous or asynchronous. The best way to reduce latency in a distributed environment is to depend on an event based asynchronous communication model. Message queues like AMQ, RabbitMQ or distributed streaming platform like Kafka can be used to implement an event based communication mechanism. However, it is important to put some checks and balances when leveraging asynchronous communication. The success and failure of the system will need to be tracked and there needs to be a mechanism to reprocess or retrigger a failed process. In the practical world, we may need to have a mix and match of asynchronous and synchronous communication based on the use case requirement. Ultimately it is the use case which will drive the implementation.
 
Logging and tracing are one of the most critical components of a distributed architecture to monitor the service call chains and aggregating logs related to those call chains. In a distributed microservices architecture, it is important to determine the flow of events through the entire system. Tracing solutions like Spring Cloud Sleuth helps to monitor those flows which then can be exported to Zipkin for visualization. Sleuth does this tracing by enhancing the log to add unique IDs (Trace id) to each request that enters the application and a Span ID to each step of the request. A single trace comprises of multiple span which identifies a specific step or section in the request. Spring Cloud has out of the box support from Sleuth and Zipkin.
 
API layer is another core component of the microservices architecture. The API layer is an abstraction on top of the services and acts as an aggregated proxy for all the services. It hides the implementation details of the services from the outside world. The API layer hides the location and the IP address of the service from the client. For the client, the name of the service will never change. The API layer takes the service name, enquires the service discovery component (like Eureka or Consul) and returns the actual IP address and port where the service is running. API layer also helps in versioning the services.
 
The complexity of a distributed architecture like microservices cannot be tamed without automation. It is therefore very important to embrace DevOps principles and practices while developing microservices architecture based applications. The code integration and deployment should be fully automated and there needs to be immediate feedback mechanism built into this automation.
 
The conclusion is just the beginning 
There is a shift happening in how we develop applications and Microservices architecture will be at the core of this shift. The applications of the future will be developed leveraging this architecture. Organizations have already started decomposing their monoliths into microservices and this trend is only going to grow in the near future.
 

Comments

Popular posts from this blog