Microservices

This topic is based on Research Spotlight Technology Review – Microservices, CMS TRB Technical Topics, 10 February 2017.

Microservices (MS) are a modern interpretation of SOAs for building distributed software systems. Each component / module of an application is developed and deployed separately. This contrasts with a traditional, “monolithic” application in which all components are developed and deployed as one piece. Microservices are well suited to DevOps methods and tools.

Monolithic versus Microservices Architecture

Monolithic Architecture

A monolithic application is packaged and deployed as a monolith. The actual format depends on the application’s language and framework. For example, many Java applications are packaged as WAR files and deployed on application servers. As an application grows to become a large, complex monolith, maintaining it may become a struggle for the development organization, and agile development and delivery may become unsustainable.

A monolithic architecture has the following disadvantages:

  • Overwhelmingly complex. Fixing bugs and implementing new features becomes difficult and time consuming. Continuous deployment (e.g., DevOps and Agile) is difficult.

  • The larger the application, the longer the startup time.

  • Difficult to scale when different modules have conflicting resource requirements.

  • May be less reliable. Because all modules are running within the same process, a defect in any module, such as a memory leak, can potentially bring down the entire process.

  • Difficult to adopt new frameworks and technologies.

Microservices Architecture

To avoid the disadvantages of monolithic architecture, many organizations, such as Amazon, eBay, and Netflix, have successfully adopted a microservices architecture pattern where applications are split into sets of smaller, interconnected services.

Business Rules and Recommended Practices

Business Rules

None.

Recommended Practices

None.

Microservices Best Practices

Netflix is one company that has successfully implemented microservices architecture on a large scale. The Netflix development team established several best practices for designing and implementing a microservices architecture This topic summarizes some of those practices (and paraphrased from Adopting Microservices at Netflix: Lessons for Architectural Design).

Keep Code at a Similar Level of Maturity and Stability

To add or rewrite some of the code in a deployed microservice that is working well, the best approach is usually to create a new microservice for the new or changed code, leaving the existing microservice in place. This is sometimes referred to as the immutable infrastructure principle, a way one can iteratively deploy and test the new code until it is bug free and maximally efficient, without risking failure or performance degradation in the existing microservice.

Do a Separate Build for Each Microservice

Do a separate build for each microservice by pulling in component files from the repository at the revision levels appropriate to it. This sometimes leads to the situation where various microservices pull in a similar set of files, but at different revision levels. This is a trade-off that can make it more difficult to clean up the codebase by decommissioning old file versions and verifying that a given revision is no longer in use.

Deploy in Containers

Deploying microservices in containers requires just one tool to deploy everything. So long as the microservice is in a container, the tool can deploy it.

Prefer Stateless Services for Improved Resilience and Scalability

Treat servers, particularly those that run customer-facing code, as interchangeable members of a group. The only concern is that there are enough servers to produce the needed work (auto-scaling can adjust the numbers up and down). If one server stops working, it is automatically replaced by another. Avoid “fragile” systems that depend on individual servers to perform specialized functions.

Create a Separate Data Store for Each Microservice

When multiple microservices share the same database, and therefore, if one microservice requires a change to the database structure, the other microservices must be updated as well. This can be avoided by giving each microservice its own data store, thereby reducing the need to update more than one microservice for a simple change in a data model.

The advantages of separate data stores for each microservice are a trade-off. Using different data structures limits reusing code between microservices. Breaking apart the data can make data management more complicated because the separate storage systems can easily get out sync or become inconsistent, and foreign keys can change, making joins between tables invalid.

If separate data stores are used, tools that perform master data management can help to find and fix inconsistencies. For example, an MDM tool might examine every database that stores subscriber IDs to verify that the same IDs exist in all.