I have never build a system comprised of distributed microservices. I have never required a microservice architecture. Our application at CenterDevice is quite large and complex. And I still haven’t seen the need to break our “monolith” into several microservices. So I have to admit that I never really grasped the enthusiasm about microservices even though I spoke to different people actually building microservice based applications. Just last weekend a close friend and excellent software engineer told me the story about a client that only uses microservice architectures for its application. Each nightly build takes 8 hours to complete because every microservice code base has to be compiled. And the deployment is similar complex.
Don’t get me wrong, any buzzword transcend its original meaning and becomes easily an empty phrase that you can make fun of. That’s not my intention. I just didn’t understand the idea of microservices until I found this article by Justin Etheredge in which he makes a very important observation. First, he cites the definition of a monolith from Wikipedia:
A software system is called “monolithic” if it has a monolithic architecture, in which functionally distinguishable aspects (for example data input and output, data processing, error handling, and the user interface) are all interwoven, rather than containing architecturally separate components.
And concludes — his emphasis:
The basic idea is that instead of being broken out into separate architectural components, things are instead intertwined. […] there is nothing in this definition about the fact that these pieces are, or are not, physically distributed from each other. We like to think of monoliths as a large single codebase, running on a single system, but that really isn’t the case. The core tenet of a monolith is that the system functionality is intertwined.
So, if we take the distributed deployment away, we realize that the architecture of our application actually answers the question “monolith vs. microservice”.
So, if we follow that course of logic, then what would a distributed monolith be? Well, it would be a set of physically distributed services that are intertwined. Sound familiar?
You see, a distributed monolith is the worst of all worlds. You’ve taken the relative simplicity of a single monolithic codebase, and you’ve traded it in for a deeply intertwined distributed system. So, are you building microservices? Take a look at a few of these symptoms, and decide for yourself:
- A change to one microservice often requires changes to other microservices
- Deploying one microservice requires other microservices to be deployed at the same time
- Your microservices are overly chatty
- The same developers work across a large number of microservices
- Many of your microservices share a datastore
- Your microservices share a lot of the same code or models
And that really rings a bell.
So when do you actually need microservices, when does they make sense?
If you start off with a monolith, your goal should be to keep it from growing into a monstrosity. The key to doing this is to simply listen to your application! I know, this is easier said than done, but as your monolith grows, keep asking yourself a few questions:
- Is there anything that is scaling at a different rate than the rest of the system?
- Is there anything that feels “tacked-on” to the outside of the system?
- Is there anything changing much faster than the rest of the system?
- Is there a part of the system that requires more frequent deploys than the rest of the system?
- Is there a part of the system that a single person, or small team, operates independently inside of?
- Is there a subset of tables in your datastore that isn’t connected to the rest of the system?
And when is the time to move to microservices?
You hear about companies like Netflix or Uber that have hundreds of microservices in their ecosystems. These companies are at the extreme end of the scale. They have thousands of developers and are often deploying thousands of times per day. They need tons of fine-grained services in order to make any of this sane and manageable.
But what they might think of as a fine-grained service is probably a medium sized application to a much smaller company. […] when you get down to the other extreme end of the scale, where you have less than five developers working on an entire system, you’ll find that there are huge advantages to sticking with a monolith and potentially pulling out a service or two — if it really makes sense.
So in the end, as the take away, Justin quotes Martin Fowler:
Don’t even consider microservices unless you have a system that’s too complex to manage as a monolith.
So in the end, our application at CenterDevice might actually be a microservice application that consists of a handful of monoliths — depending on your point of view.