November 24, 2015 | Written by: Doug Rothert
Share this post:
The buzz around microservice architectures is clearly building. More and more people are discovering the benefits of splitting large monolithic services into smaller microservices. These microservices have a standardized interface that enables them to tolerate individual service failures and updates without catastrophically impacting the overall business solution.
People want to know how to get started. There are excellent resources available, but you first must decide whether to build a monolithic solution (Brownfield) and convert it to a microservices architecture, or to build a microservices architecture from scratch (Greenfield). There are strong opinions on both sides of this issue, including Martin Fowler’s MonolithFirst and Stefan Tilkov’s Don’t Start with a Monolith. In this post, I will distill some of their arguments, find common ground, and present my own perspective for people starting to use microservices.
Contrasting “MonolithFirst” and “Don’t Start with a Monolith”
There are two key arguments against starting with microservices in “MonolithFirst”: that microservices add potentially unnecessary complexity to new projects that usually need rapid evolution, and that it is extremely difficult to accurately determine the boundaries of each service when you start a project. Fowler says that if you have a working monolithic service, you can deconstruct it into microservices either by pulling it apart incrementally or all at once, noting the natural boundaries:
Should I try to make a monolith first and then break it into microservices?
“Don’t Start With a Monolith” states that it is very hard to split an existing monolith into microservices if it was not designed to be split. Tilkov points out that monolithic services are often tightly coupled with loosely defined interfaces, which makes the redesign to split them into well defined microservices extremely difficult. The best way to ensure that your microservices have well defined boundaries is to design that into the architecture at the beginning. Ideally, you are experienced with the domain and can use that knowledge to make the correct architectural decisions when you build a second version of the system:
Or should I just try to build a microservice architecture without it?
Both of these arguments center on the boundaries between services—what is the scope of each service and what interfaces define it. This is the common ground, and having these boundaries well defined is crucial for successful microservices. Fowler argues that working with an existing implementation is the best way to find this, while Tilkov states that it must be planned from the start, ideally with enough domain knowledge to avoid serious mistakes.
Learning the most from both views
My perspective is that real world situations and systems require aspects of both. I lean towards Tilkov’s perspective, but ask yourself some questions about the microservice architecture that you intend to create and use the answers to help take their advice more effectively.
- Think about your existing assets. Do you have a monolith to start working from? If the answer is no, your only option is to pursue a Greenfield approach. Take a serious look at all open source projects in your domain—successful and not— to learn what has and hasn’t worked before you build your model. This can help to define the right boundaries before investing your own time and money
- Take a hard look at your monolith (if you have one). What does the monolith look like both conceptually and underneath the covers? Specifically, does it have well defined boundaries between its components? Can you clearly see the scope of each component and a standardized set of interfaces that make sense? If this is the case, you may be able to refactor some of your existing monolith into a set of microservices
- Take a hard look at those components of your monolith (if you have one). Of your existing components, which are critical? Which are unstable? Which change frequently? If you have components that are critical, stable, and infrequently need change, don’t try to change them. Typically you want to start with an incremental replacement approach, first focusing on components that are non-critical, unstable, and prone to change. If they have well defined boundaries, they are good candidates to convert to microservices because they will benefit the most in the long run.
When weighing the points above, remember that a good microservice is one that not only does its job effectively but has a limited blast radius when it fails, allowing the overall business solution to work.
Changing an architecture is a journey
As you get started with a microservice architecture, remember that adopting a new architecture style is usually an ongoing process. At first you should concentrate on the small wins that can build confidence and support a standard approach that you can repeat. Try to read as much as you can on microservices (including the resources listed below) to broaden your perspective. One of my favorite expressions is “your mileage may vary” because it neatly expresses that individual experience is unique, and your path to microservices will be no exception.