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
Post a Comment