Unless you’ve been living under a rock for the past few years, you’ll have no doubt heard about the wonders of microservices. It’s an approach to building and delivering software that has been adopted by the likes of tech giants such as Netflix and Uber, and now it’s found its way into enterprise software.
Microservice architectures have a lot of benefits, and decoupling your applications into smaller components is generally a great idea. However, for every advertised advantage that adopting microservices has, there are terms and conditions to know of.
In this post, I will line out the fine print behind some of the proposed advantages offered by a microservices architecture, and why a great number of organisations are not seeing the benefits promised to them by conference speakers and expensive consultants.
One of the most commonly touted arguments for microservices is that your application will be more fault tolerant than the monolithic alternative. The idea behind this is that a single component of the application failing will not bring down the entire application because they are running as separate processes, which is indeed true.
However, unless you have specifically built your applications with fault tolerance in mind, you’re simply increasing your points of failure from one to exp(n), where n is the number of microservices you have. When you adopt microservices, you also adopt the challenges associated with distributed computing, and ignorance of these challenges is a sure fire way of making your application more brittle than ever.
In a monolithic application, you simply call a business class and the only thing that is likely to fail is your database call. When your application is communicating via HTTP (or RPC if you’re fancy), you are just giving your application more opportunities to encounter failure. You have to consider the fact that one of your other services may not always be available, and build your application in a way that a single service going down won’t take down your entire application.
Lower Cognitive Load
One of the hardest parts of starting a new job or project is familiarising yourself with the problem domain and codebase, so only focusing on a single bounded context means you can become productive much quicker than they would on a monolithic application.
However, if your team is responsible for every service in the application, onboarding a new team member is far slower than on a monolith. Having a new member of staff try to get 10 microservices and backing services set up on their machine is just plain cruel, even with Docker. And don’t get me started on if the microservices are all written in different languages.
What a lot of teams forget is that microservices are just as much an organisational pattern as they are an architectural one, and by organising your teams in the exact same way, you are pretty much throwing away one of the key benefits of microservices. The traditional analogy for team size is two pizzas- meaning the team must be of a size where two large pizzas could feed them lunch.
Deploy More Often
We’ve all heard the stories about hundreds of production deployments per day at the big tech companies. It must be a best practice™ if Uber and Netflix are doing it. Being able to deploy to production multiple times per day stops us developers having to be in the office by 6AM for the classic ‘big bang’ deployments, so I am naturally a huge fan of this.
However, you can only deliver software as fast as your organisation allows you to. In the enterprise, it’s very rare to have systems that can be deployed whenever you want. In the real world we have contracts with clients to consider, industrial regulations, change control processes. Not everybody is going to be lucky enough to be totally in control of when they deploy, and your architecture is not going to change that.
In order to achieve the holy grail of continuous delivery, you need organisational buy-in from the top down, and potentially from external parties such as clients and regulatory boards. There are a number of rather large books out there dedicated to this topic, so it’s never going to be as simple as “we’ll just do microservices”. I’ll say it again: microservices are just as much an organisational pattern as they are an architectural one.
I mentioned ‘big bang’ deployments, where the entire application is taken offline for a period of time while the application is updated, and potentially the database migrations are run. Microservices are advertised to reduce the scope for things going wrong by only deploying parts of the application that have changed.
However, if you are not deploying quality code, you are not going to have safer deployments regardless of your architecture. I understand that quality is a very loaded term, but I mean quality in the simplest of forms in that it does what it’s supposed to do. If your monolith is frequently shipping with show stopping bugs, your microservices will too.
A good quality assurance process should be the priority before you try decomposing into microservices, and ideally you should have a complete test suite in place before you even start writing code. Ideally this should be automated, and integrated into your pipeline to ensure that your deployments are as safe as possible. Then it’s time to start thinking about microservices.
Reading this may give you the impression that I don’t like microservices, but this is simply not true. I think microservices are a fantastic way to build software, and many teams have had incredible success by adopting them.
It is important to note, however, that they are not a silver bullet for all of our problems. Implementing microservices requires far more than simply splitting your application into APIs: it requires an organisational shift, and solutions for problems not required in a monolithic application.
This is perhaps one of the less glamorous aspects of the microservices journey, and it has been left out of pretty much every blog post and conference talk I’ve watched on microservices. I’ll say it for a third and final time: microservices are just as much an organisational pattern as they are an architectural one.
If you’re familiar with Conway’s Law, you’ll know that an application’s design will often mirror that of it’s organisation. If your organisation is a dysfunctional mess, then your application will be one too, regardless of architecture.