Is there a paradigm shift with Microservices?
Current digital disruption and cutting-edge mobile technologies have imposed new requirements on server-side applications. Today, server-side applications are expected to support desktop, mobile, and hardware devices (such as Internet of Things, or IoT). The Application Programming Interfaces (API) that are used to consume various features of the enterprise application need to achieve complex integration services and need to interact with business logic, databases, or other services which may contain data in multiple formats (JSON, XML etc.)
There have been limitations in the past: network bandwidth, data parsing, cost of network, and low server performance, which were constraining the development of enterprise solutions. However, these are no longer limitations. Monolithic systems with one WAR/EAR file for the enterprise are now being simplified. Microservices are gaining popularity.
But are microservices really as revolutionary as they claim to be?
Monolithic Architecture is a style of software development popular since the mainframe days. In this style, the entire code of the application is in a single code base, compiled together and packaged into a single archived file, called WAR or EAR, which is an executable that will be deployed as a single unit. The code may still be well-structured, but it is not isolated into separate modules. A comprehensive regression testing must be followed even in the case of simple changes.
For example, let’s say we were building a web application. To start, we will use the layering approach, the web application will have a Presentation layer, a Business layer for business logic, an Integration layer for loose coupling, and a Persistence layer for database logic. In order to run the application, archive files (WAR/EAR) are created and will deploy on the server. Since all the components are packaged as a single deployable unit, it is usually referred to as a Monolithic application. Even though we have separate layers and distinguishable components, all are packaged under one deployable component.
Monolithic Application comes with various challenges. It intimidates developers during troubleshooting and debugging. After some point of time, it’s very hard for the developers to make any changes, leading the system to become highly unmanageable. Other things that can become problems in Monolithic application include:
- Integrated Development environment tools get overburdened, resulting in longer time for refactoring, build, and deployment.
- Scalability is resource-consuming and difficult because it needs multiple copies of the whole instance on every server behind load balancer.
- It can be very hard to upgrade the technology stack version due to dependency and incompatibilities.
- There is a huge regression testing effort, even for simple changes.
- Frequent production downtime is required: in order to update one module, the entire application needs to be redeployed, hence the availability is impacted.
- Maintenance and documentation are difficult.
Primarily, organizations across all business domains need to ensure that their services are available through all digital channels and are scalable, easy to deploy, and easy to adopt or to migrate over to newer technologies. This provides an edge over competitors offering similar technological innovations. Microservices architecture is more suited for today’s world, as it enables an organization to cater to the aforementioned needs.
The term “micro” refers to the sizing. In the Microservices-based architectural style, a single application is developed as a suite of small, independently deployable services. Each microservice runs in its own process and communicates with a lightweight mechanism, often an HTTP resource API. A microservice must be manageable by a single development team. These services are built around business capabilities and are independently deployable by fully automated deployment processes. Independent deployability is key - it will enable separation of concerns, as well as independent evolution of technology stack and functionality.
Monolithic "vs" Microservice: “A simple Use Case”
Imagine that we are building an e-commerce application that takes orders from customers, verifies inventory, takes the payment, and ships items. The application consists of several components including the Ordering UI, which is the primary user interface, along with some backend services for product catalog, payment, inventory management, and shipment.
With Monolithic style, every component or module will be packaged into a single deployable unit.
On the other hand, using the Microservice, the e-commerce components will be separated into isolated components, which will interact with each other using simple, light-weighted REST API’s.
Some noteworthy Microservice advantages:
- Independent code base
- Each service has its own software repository.
- The code base is easily maintained for developers; they can work faster and make new changes more freely. New team members become productive quickly.
- There is an easier build, test, and refactor.
- There are no direct dependencies between code bases.
- The code is organized around business capabilities.
- Independent technology stacks
- Each service is implemented on its own technology stacks.
- The technology stack can be selected to fit the task best.
- Teams can experiment with new technologies within a single Microservice.
- Independent evolution of features
- Microservices can be extended without affecting other services. For example, new versions of the UI can be deployed without redeploying the whole system.
- It is very easy to upgrade the version or adapt a new framework.
- Easy integration and deployment
- The integration is easy and there is automatic deployment (using open-source continuous integration tools such as Jenkins, Hudson, etc.)
- The web container starts more quickly, so the deployment is also faster.
- It is easy to scale and integrate with third-party services.
There are, of course, challenges faced in implementing Microservices, to include:
- In the initial phase of application design, the designer needs to be very clear about the business requirements and need to spend more hours on designing the best-suited way of inter-communication between services and putting together best architecture design.
- The major drawback of Microservices is the complexity that arises from the fact that a Microservices application is distributed. This means that developers need to choose and implement a proper communication mechanism--they must write code to handle partial failure when dependent services are not available or responding slowly.
- Business transactions that require multiple databases are very hard to manage.
- A Microservice application typically consists of many services. Each service will have multiple runtime instances. Also, there is a need to implement a service discovery mechanism, which will enable a service to discover the locations of any other services it needs to communicate with.
- Due to distributed and multiple hop nature, testing becomes complex and tedious.
- The architecture brings additional complexity as the developers have to mitigate fault tolerance, network latency, and deal with a variety of message formats.
- When the number of services increases, integration and managing whole products can become complicated.
- A higher level of collaboration is required between different teams, as an issue in one service can impact other services.
- Managing version and dependencies between the services is difficult as they all have their own development and deployment cycle.
When should you use Microservices?
Microservice-based application development is not really a new a paradigm shift. In fact, the UNIX design philosophy is almost identical. Although there are many advantages of using Microservice-based architecture, it is not a solution to all application development and deployment challenges.
Building complex applications is inherently difficult, either with Monolithic design or Microservice. A Monolithic architecture only makes sense for simple, lightweight applications while Microservices will increase system complexity, the cost of servers and maintenance. A better approach to design and develop an application is to design a Monolithic application with core business functionality and split peripheral functionalities around the core into Microservices. Implementing Microservices can be a journey, and careful business and design considerations need to be made when starting out.