A microservices is a software module that is developed, deployed, and released independently. Multiple microservices, working together, comprise of an application. Properly used, microservices enable organizations to scale their development processes even as overall application complexity grows.
Many companies began shifting from a monolith application to a microservices-style architecture in the early 2000s. Early adopters began to separate the pieces of applications, and using small shim libraries and APIs, stitched them together when necessary, instead of using one application.
Today, microservices are a common architectural method for developing cloud software applications. Microservices generally follow six principles:
- Loosely coupled. By having one team per service, a small, dedicated team manages and “owns” a single microservice. The team is entirely responsible and in control of making decisions that are best for the microservice.
- Standardized. Services must be easy to test and maintain. Each service should have standard operating procedures, how to troubleshoot and handle errors, and how to maintain it in the greater architecture. A service should withstand tests, rollbacks, and upgrades.
- Decentralized. Each service has its own isolated codebase. When code and its dependencies are together in one place, the team is responsible for all aspects of managing that part of the business: development, build, troubleshoot, document, deploy. This allows the team to function independently of other teams.
- Decomposed. When an application is decomposed, it is broken down into microservices, which, individually, much meet a single business need. Because each microservice is isolated, their purpose and intention must be specific and reusable to a business need. The modularity allows service teams to work cross-functionally if new features or products require different services.
- Resilient. Only one microservice has to fail. The design of microservice architecture allows healthy services to remain “up” even if one goes down. Only one part of your application becomes unresponsive until the microservice is fixed, minimizing the impact on end-users.
- Intentionally Designed. Multiple services must grow and change together. When you adopt microservices, it’s best to anticipate they will evolve as the software and userspace evolve, so architect your services accordingly. Microservices will then endure these changes and adapt to remain viable.
Microservices principles have been hugely influential in the evolution of cloud applications. Companies such as AirBnb, Netflix, and Yelp were at the forefront of the microservices revolution. That said, microservices are not a panacea, and some organizations that have adopted microservices have moved back to a monolith.
A common question people ask is “How big (or small) should my microservice be?” One common answer is that the size of a microservice can be variable, but it should be coded by no more than a dozen people (the so-called “two pizza rule”).
This definition, while helpful, answers the wrong question.
The real question is “How do I scope my microservice?” Once the scope is defined, the other details of a microservice: team size, composition, process, technology, and so forth — become possible. Without a clear scope and requirements, none of these questions can truly be answered.
In a microservice architecture, developers can iterate on a given feature or function independent of the other services. Thus, a pragmatic approach to scoping microservices involves identifying a unit of functionality that deserves independent iteration.
For example, imagine a simple ecommerce site. Will you want to independently iterate on the shopping catalog separate from other functionality? Probably. If you look at the shopping catalog functionality, perhaps it also includes customer reviews. Will you want to independently iterate on the review functionality separate from the shopping catalog? Probably. Will you want to independently iterate on viewing reviews versus authoring reviews? Possibly.
In a monolithic architecture, you are limited to a single, fixed size unit of iteration: the monolith. The true power of microservices is that it allows developers to independently iterate functionality of arbitrary size and scope. You may want to iterate on a single, small function, or a broad class of functionality.
Adopting microservices to improve your developmental agility requires you to think differently. Thinking about the specific features or functions that will most benefit from this agility will enable you to truly take advantage of this new architecture.