We have re-engineered multiple products from being monolithic to being microservices. This blog gives you an overview of how we transformed and migrated from monolithic to Microservice based architecture at Equinix.
The monolithic application was developed using Java, packaged as WAR files, and deployed on Tomcat application server. Successful applications have the inherent habit of growing over time and would surface as a monster monolithic application, the result is an extremely complex application.
It's time to migrate to microservice-based architecture when the application is simply too large for any single developer to understand it fully.
Splitting the Monolithic
Domain-Driven Design by Eric Evans was the big influence on microservice architectures. This is ostensibly a technique to decompose a large problem space into domains.
This is one of the important activities in this journey. Prepare the functionality matrix to list down all the current functionalities and associated package and class files. Organize business capabilities, which are copies of your organization structure.
Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure. — Melvyn Conway, 1967
Design APIs endpoint behavior by describing them in common ubiquitous language that stakeholders of the project can understand. The domain-driven design or API-contract-first approach is used for defining a contract for each microservice.
Tackling Architecture Challenges
Any application rewrite will have architecture and engineering goals. Adapting microservice architecture should address the below engineering and architecture goals.
Domain (private) APIs are microservice endpoints. Microservice endpoints are domain functionalities that might not be directly exposed to customer channels.
In regards to experience (public) APIs, applications will have multiple experience channels. Demands with respect to each given channel will be different; to embrace innovation in each channel requires different API contracts. Experience APIs will be created by orchestrating one or more microservices.
Domain-driven design (DDD) helps the team to create a service contract. It's the model between the business and IT stakeholders that the team can use to communicate with the business requirements, data entities, and process models. The model is modular, extensible, and easy to maintain, as the design reflects the business model.
Swagger is a powerful open-source framework backed by a large ecosystem of tools that helps you design and document domain models for the given service which include input, output, and error parameter. It can be shared as an API document and specification.
The next big challenge is to select the right technology to implement a microservice-based architecture. Developers don’t need to share infrastructure; they can implement each service in a technology stack suitable to the complexity of the problem, however, to start this architecture style limited to a few technology stacks will help the company to reduce time to market.
Second, standardization has always been a mantra of IT organizations as a way to reduce costs and increase agility. Choose a programming language for service development and create end-to-end lightweight opinionated software framework that enforces the twelve-factor app standards so that the team can get started with minimum fuss and focus more on business logic in microservice-based development.
Spring Boot makes it easy to create stand-alone, production-grade Java- and Spring-based applications.
Node.JS is an extremely lightweight open-source platform that’s driven by a passionate community. It is rich with ever-expanding modules contributed by enthusiasts and has a vibrant online community. Modular architecture goes nicely hand-in-hand with microservices.
In application development, there are two different type of environments:
Developer environment, where developers write the code.
Deployment environment, where the operation team manages the application.
Moving code between these two environments will lead to technical errors, lengthy time delays, and miscommunication.
Docker containers enable us to build the ship and run each microservice code in different containers. It is easy to configure, and provisioning the microservices stack in any environment is one click away.
Automating the cumbersome manual routine DevOps tasks in operation is key for microservice-based application deployment. Agile development techniques encourage developers to create tools to automate many of the cumbersome manual routine task in operations, referred to by many as the DevOps revolution.
This has brought development teams and IT operations closer together using advanced tools like Puppet, Chef, Kubernetes, and Docker.
Selecting right architecture pattern and service collaboration techniques is an another important aspect of this journey.
Pattern 1: Microservice With REST Endpoint-Based Collaboration
Highly distributed and scalable.
Complex orchestration and interaction.
Deployment pipeline requires much more planning.
Over a period of time, it’s hard to manage.
Microservices will communicate each other if needed.
Pattern 2: Microservices With Event-Based Collaboration
Use events to implement eventually consistent business transactions that span multiple services.
The event queue is used to orchestrate the microservices based on events defined for each API contract request.
Pattern 3: Microservice With Orchestration Layer
The orchestration is used to orchestrate microservices based on the workflow defined for each API contract request. Orchestrators are excellent at handling the requests in a generic way, establishing a set of rules that allow fully customizable API contract for each channel — like portal, mobile, and API.
Avoid Pattern 1. Patterns 2 and 3 are equally good; it deepens based on nature of your product requirements. Based on our experience, Pattern 3 is an ideal fit for large-scale product development. Also, we have started exploring microservice-based architecture 2.0 (feature-based development for our product developments. We will share more details soon.
However, our experience with the integration or orchestration of different microservices is that it is considerably complex — not only in terms of custom mediation logic (which must be as complex as the end customer API contract demands with respect to a given channel) but also at the level of transactional control and correlation (even parallelism and performance).
If the right set of tools is not given in the microservices world, developers will look elsewhere.
Security Is Not An Afterthought
One of the important goals when we build systems with end-to-end architecture is statelessness. Maintaining identity and access management throughout a sea of independent services will be tricky.
Compared to the traditional monolithic structure that may have a single security portal, microservices pose many problems. Should each service have its own independent security firewall? How should identity be distributed between microservices and throughout my entire system?
JSON web tokens help achieve the end goal of creating a distributed authentication mechanism for microservices that are self-contained, standardized, and easy to replicate.
If the right set of tools is not given for microservice monitoring, there is a high chance that the entire initiative will be in jeopardy. A few monitoring principles are:
Monitor what’s inside the container.
Alert on service and container performance.
Monitor APIs endpoints.
End-to-end correlation ID stretching for the given request.
Leveraging the below telemetry techniques will allow you to establish more effective monitoring as you make your way towards microservices.
APM (Application Performance Management) consists of a stream of events that can be used by tools outside the cloud to keep tabs on how well your application is performing. Pinpoint is an open source APM tool for large-scale distributed systems written in Java.
Stream events and data that make sense for your business that you can use for your own analytics and reporting.
Health and system logs that are provided by your platform.
Application logs with end-to-end correlation ID stitching and performance metrics on each method level for the given requests.
How an architecture style will influence the restructuring the development team.
Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations. — M. Conway
The influence of Conway’s law in software development? Your architecture reflects team structure. Organizations are now organized cross-functional teams built around domains rather than structured around technology layers. For example, the domain team includes business analysts, UX, Developer, DBA, and IT operations. — Venkat Rangasamy
In future articles, we’ll discuss more details about the 12 factors standards for microservices and microservice architecture 2.0. Stay tuned.