5 Giveaways On Microservices Architecture

Gabrio Tognozzi
4 min readFeb 14, 2021
Image by Gerd Altmann at Pixabay

In this blog post I’m writing down some personal thoughts about the design of microservices architectures. These considerations are for the readers but also for me as a reminder for the future.

Do Not Over-Engineer The Technologies

Most of the time the companies that adopt microservices based architecture out there, at least in Italy, are made of young people like me, that are always excited about using the most modern technologies. In my opinion this is not the proper choice for projects that are not for R&D: while R&D development teams are allowed to dare with such choices, if the client I’m working for has strong stability requirements and strict deadlines, I would rather trade excitement and uncertainty for boredom and stability. I found the Mitre: Assessing Technical Maturity publication really interesting, you might like to read it.

hype cycles

Do Not Over-Engineer The Architecture

Microservices add, on top of the already known software complexities, a lot of new challenges:

  • You will now have to struggle to maintain Integrity of data across all the services, and accept to live with Eventual-Consistency;
  • The Atomicity of mutations that span multiple services is hard to achieve, you’ve to handle distributed transaction exceptions across different services;
  • You’re constantly threatened by unattended race conditions: would you really be betting on having correctly handled all the possible race conditions of your distributed system?

After all the above statements, if they are reasonable assumptions for you, then you must agree with me that not every system is best represented by this architectural approach. In my opinion the best would be to adopt an hybrid architecture. If all the parts of you’re application is designed for billion of users, then there is no escape, but in most cases we can separate a project in two groups:

  • Part of the system will be physically limited to a certain number of concurrent accesses, this part would be best represented by a monolithic design;
  • Another part of your system will be required to scale to possibly billion of users, this is the right place to adopt the microservices architecture.
over-engineering

Consider The Worst (but possible!) Case

We are software engineers, and we solve problems. but we are way better to create ourselves more problems than we really need. FML. At work, at least, it is important that we do not fight problems that will never actually exist. This concept was driving the previous chapter, and it was somewhat already implicitly expressed, but anyway this is a core concept and deserves a chapter on its own.

One of the skills that senior engineers bring with them is the ability of drastically reduce the domain of all the reasonable possibilities. The first times I heard someone make this kind of considerations was for me a moment of epiphany:

Are you telling me, that if this system has to model the back-office of a medium-size business, then it won’t have handle ten billion users?

In general, if the target of your application is a physically finite resource, you may add a percentage to that maximum value to stay safe, but you just don’t need to handle 100x of that amount in your system.

Performance Testing And Observability

This chapter is applicable to all the kind of architectures, but once you start working on a microservices oriented architecture, you can’t affort to not invest on Observability and Performance Testing.

  • Observability: differently from the monolithic architecture, were you can find all the logs of you’re application in one place, when dealing with microservices architecture, you will have all your interesting logs fragmented in many different places. The microservice architecture also brings with itself a new whole universe of bugs related to the integration and interaction among different services. Something like the ELK stack is strictly necessary.
  • Performance Testing: if you’re using the microservice architecture, you’re most likely trying to handle a high throughput with your application. Start testing as soon as possible the performances of single services, and the system as a whole for bottlenecks. This is the best way to avoid investing week of works building on top of weak assumptions.
fixing bugs

Prefer Managed Services

The last chapter is about using managed services. Kubernetes clusters, Kafka streams, and Databases are way cheaper on-premises than managed for sure, but it does require so much effort to properly setup and maintain such core components that the game isn’t worth the candle.

In my opinion it is a good idea to use on-premises services in testing environments, maybe also in staging, but I would prefer having managed services in production environments, rather than having to rely on internal resources to manage and maintain such complex parts of the system. If you’re a small or medium size company you may cannot afford to devote human resources only to maintaining your production infrastructure.

Conclusion

I hope you found this blog post interesting, these were some considerations about microservices architecture. If you’re interested on posts like this leave a clap and follow me.

--

--