Why are we talking about this again‽
So here we go, another blog post about microservices and how they're amazing or how they're terrible.
Fear not! Even if you already know everything there is to know about microservices, or if you once used them and you never want to go back there again, this blog should have
something for you.
The essence of the question is not whether you should be using microservices. It’s about how you go about designing your systems from day 0 to make sure that, when you're massively successful and deciding how to spend your millions, your systems don't suddenly decide to go on holiday with you. The last thing any of us want to do is spend Friday night sweating at a terminal screen trying to work out why that background coroutine, which has decided to stop working, was the key to making your entire system work.
When your entire dev team has gone home (or to the pub) the buck stops with you - you're the one who has to fix it.
How often has a new CTO joined a company, full of excitement and hope, only to find hordes of legacy systems, unexplained and undocumented code and strange processes running on a Windows NT server? There’s also bound to be that weird unknown line, which, if you comment it out, will break absolutely everything.
Not only does this cause a form of a existential angst and make you question why you got into technology (don't worry, this is a common phenomenon), it also means those exciting new projects that you wanted to get off the ground suddenly don't seem as possible and realistic.
How are you going to integrate your favourite new language (Golang of course) with windows NT? How are you going to deliver and make a good impression at board level? How can you avoid all this mess in the first place?
For some of the answers, keep reading!
What is a microservice anyway?
You've probably worked out by now that this article isn't really about microservices, but they do represent a very good illustration of this all-too-common problem. So, what are they?
Microservices is quite a broad term representing an architectural approach.
A) Keep all of my code and processes in one large repository, deployed in one binary on a single machine (probably with good multithreading and autoscaling in place)
B) Split out these processes into logical chunks that can live in isolation, and deploy them completely separately as standalone binaries
Option B is a microservice approach.
For example, I have an API for my website. It searches an address database for when users sign up to my system, it processes payment details when subscriptions are due and it performs mathematical functions for some other reason.
A more traditional and monolithic approach might be to have the code that deals with this all together, perhaps in one front facing API with maybe a couple of service files to help out. A microservice approach would be to build three separate, tiny APIs - one for each job. They live in complete isolation and have no knowledge of each other’s existence.
What’s the benefit of this? To put it in a nutshell, simplicity and scalability.
It is much easier for engineers to deal with a narrow vertical slice of a system rather than a wide broad one.
Imagine that amazing, clean, simple, efficient API that you've always dreamed of maintaining. Well now you can maintain dozens (or even hundreds) instead of one vast sprawling code base.
Not only that, you can identify and fix bottlenecks in record time. Maybe your mathematics processing is taking too long. Well now you don't have to modify the entire code base. You can just focus on that one micro API.
Have some legacy code that you can't integrate with? Well, why don't you update just a tiny piece of it to the latest technology and then integrate with that one micro service? Trust me, this is a much more appealing task than trying to integrate with an entire legacy system.
At this point, you’re thinking this is amazing how do I get started? At least I hope you are. The good news for you is that there are tons of services out there designed to make developing microservices easy.
Ever heard of AWS lambda? AWS Fargate? Kubernetes?
The solution? The right tool for the right job.
So far, I've painted a pretty rosy view of these things. Does this mean that you should jump right in regardless and start using microservices? Of course not. There are inherent challenges that need to be overcome when implementing a microservices architecture. This is where you need a really good architectural design, that not only solves your current problems but also considers where you're going to be going in the future.
There is a complexity payoff curve. At the beginning of a product life cycle, it is much simpler to get going with some off-the-shelf technologies, for example Express and NextJS.
There’s inherent value in doing this, a business often needs to get a product to market fast in order to validate it and potentially raise investment. The last thing on your mind at this point in time would be DNS routing, message brokerage and state management between microservices. It could also be that the system that you are designing and working with just does not suit microservices.
And herein lies the problem.
You are under pressure to perform, fast. Success means scaling technology, scaling technology means tech growing pains and all too soon you are staring at significant re-architectures and re-writes. Either that or your terminal screen on a Friday night.
What if it’s too late?
If you happen to be reading this at 10pm on a Friday, bleary eyed and on the verge of tears, do not worry, there is a ray of hope.
Big projects start with small steps. Identify the most disgusting piece of code, the most problematic service in your entire stack (it probably won't take you too long), rip it out, turn it into your first ever microservice and set up the communications between them.
Congratulations, you're a microservice company. Stick it on your company prospectus and your valuation might just increase!
And what if you’re starting out from scratch? It is unlikely that you're going to want to start with a microservices architecture. There is a certain amount of overhead which will probably prohibit you from making the fast progress that you want. However, it is vital that you start with good design inside your code. It is possible to mirror a microservices architecture. Plenty of inversion of control and good use of interfaces can set you up for success. In the future, one interface can quite easily become one microservice. Separation doesn't have to be on the machine level, it can be on the code level too.
If this article can get even just one more CTO in the pub and out the office, then I will consider it a success.