Microservices, what I’ve learned
There are hundreds of stories like this
Many years ago, when I was a young and ambitious programmer, I joined a fresh start-up. At the time, I didn\’t have much experience with microservices. Neither did my senior teammates. However, from day one it was decided that we needed to base our solutions on a microservices architecture. In retrospect, I have to admit that there was a lack of someone who loudly asked Why?
Why microservices?
In my previous post, I described some common statements that we will always hear when discussing system architecture. In a discussion about microservices, we will always hear theoretical statements talking about their advantages:
- Deployment/release independence. Each of our microservices has its own individual lifecycle, independent of other parts of the system.
- Scalability. We can scale the individual microservices independently as required.
- Resilience. Errors in one microservice do not affect the rest of the system.
- Maintainability. Individual teams are responsible for maintaining and developing small microservices, making the work easy and enjoyable in the long term.
- Single Responsibility Principle: Each service should have a single, well-defined responsibility and should not be concerned with the implementation details of other services.
- … (and many more buzzwords)
Why not/don’t microservices
When talking about microservices we should always keep this quote in mind:
If you can’t build a well-structured monolith, what makes you think microservices is the answer?
Simon Brown
Monoliths have a very bad reputation for many reasons. In most cases, these are very unfair and inappropriate opinions. Programmers confuse a good and solid monolith with the so-called big ball of mud. And is there anything worse than a bill bag of mud? Yes, a distribiuted big ball of mud. The graphic below illustrates this well:
In fact, what we are really doing is randomly cutting out certain parts of our system. Then creating new services and using the network to communicate between the components. Having one component (the big ball of mud) was bad, now it’s even worse. We added another complexity to our system – the network. The fallacies of distributed computing were described long ago. Let me just list them:
- The network is reliable;
- Latency is zero;
- Bandwidth is infinite;
- The network is secure;
- Topology doesn\’t change;
- There is one administrator;
- Transport cost is zero;
- The network is homogeneous.
In our distributed architecture they are our concern.
Unfortunately, this is not the end of the technical complexity that has been added to our system with microservices. In order for our services to communicate at all using the network, they need to know about each other. So we need to introduce a mechanism into our system called Service Discovery. There are, of course, ready-made tools, the use of which we must of course learn.
In addition, along with microservices, we need to introduce an appropriate deployment method. So, docker and kubernetes will sooner or later arrive in our system. Their use is very simple and obvious…. at every presentation.
We must not forget about version management of our microservices. Especially if one service is running several different versions in production.
It is equally important to maintain and not break conracts between the APIs of our services. A classic mistake, trying to solve this problem, is to use e2e tests. A better idea is to introduce consumer driven tests, but this is another complexity in our system.
So what should I do?
- First, define well what kind of system you are building.
- Consider carefully the contexts in which you will be trading.
- Is the solution stable, the domain well modeled, or are you exploring new territory?
- How much time do we have before going into production?
- How complex is our product?
If it’s a new cryptocurrency payment platform and even before its launch you already have 1mln+ users waiting to make 1mln+ transactions, scalable microservices seem like a good idea.
If you’re a small startup, your product is going to reach a narrow audience, it’s going to be built by one team of 3 developers and you’re really struggling to find reasons why your system wouldn’t perform well as a monolith, then just don’t build microservices and stay in the safe harbor.
Summary
This relaxed flow of thought was just the tip of the iceberg when it came to the decision between choosing the right architecture for our system. However, what I think is most important is simply to remember that building a monolith is much easier and faster, and if we don’t have any special criteria that our system must meet, we should choose simple solutions.