Macro Problems? Micro Services!

Let me ask you a question — how do you approach a complicated problem?

If your answer is “break it down into smaller problems, and solve each problem individually” than, apparently, we think the same way!

We can use this problem-solving technique to build sophisticated systems and even make the systems work (eventually).

Before we talk about microservice architecture, it’s important that we first define what microservice architecture is:

“The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms” — Martin Fowler

Now that we have the definition down, I’d like to share a story that will explain why I decided to implement it on my own systems.

I’m a backend developer at WSC Sports — we help media rights owners maximize their content with automated, near real-time highlights in an automagical* way. As part of my job, I design and build real-time and scalable systems. And let’s face it, it’s a huge challenge to think about the future of your brand new system before you even write a single line of code.

When I started to design my system architecture, I asked myself these three questions:

1. Does it need to support huge scale?

2. Does it need to be fast?

3. Will it be easy to maintain?

Sometimes, you just don’t know how to answer these questions all at once, so I decided to build a monolithic system.

I chose monolith because it was fast to program, easy to monitor, and it even ran quite fast. The system worked fine, until one night, when the system started getting a huge amount of jobs to handle. Worse than that — not only was there a larger number of jobs than expected, each job was bigger and more complicated than we had before. Eventually, it made the system run extremely slow that night and we had to solve the problem ASAP. The quick fix was to scale up our system so it will be able to handle a large number of requests and be able to finish them in a decent amount of time.

The problem with scaling up the system was that we had to run it on expensive machines just to make sure that it will be able to handle this kind of scale in the near future (even if most of the time we only need to handle small jobs, on a smaller scale).

That night made me realize that something needs to change, so I started thinking about a new architecture for my system.

Yeah, you guessed right, microservices architecture was the design I chose, and these are some of the reasons why:

  1. It can handle a big scale (scale out when needed)

  2. In case of a system failure, you can quickly fix the problem and deploy the updated microservice instead of the whole system

  3. As time passes, systems often require refactoring and that was a great opportunity to make the system components decoupled and easier to test

I started breaking down my monolithic system into small logic units. Each logic unit has a single responsibility, it is decoupled and stateless, and all these logic units communicate using queues.

This architecture-change process taught me to keep things simple! It makes the debugging process and problem solving much easier, and will make your code easier to read. Another thing that helped me a lot was to have a well planned CICD flow, which made my life easier when I needed to upgrade or fix some bugs (even though my code doesn’t have bugs at all!) in one or many microservices’ code.

And one last thing — monitoring your system performance is both crucial and easy when using microservices (using logs, BI reports, slack alerts etc.), so make sure you do. You will instantly know which microservices happen to be the bottleneck of your system, and you will be able to fix them specifically.

Eventually, changing the architecture from monolithic to microservices-oriented wasn’t as fast and easy as I expected. But moving to microservices architecture helped our development team confront problems that we frequently faced before, such as avoiding a single point of failure, so we could fix this scenario before it ever happened. Scaling wasn’t a problem anymore, and the system performance got better even with cheaper servers than the monolithic system required.

I do want to stress one important point: Although microservice architecture is becoming more and more popular among software developers, you may not want to jump the gun and implement your system to be microservices oriented. If your system doesn’t need to be complicated and big and support large scale, then monolithic or other approaches may still be the better fit for your system.

Good Luck!