DEV Community

Cover image for Yes! Use microservices and ask 'why are you like this?' afterward 😑
Adriano Galello
Adriano Galello

Posted on • Originally published at gdi3d.github.io

Yes! Use microservices and ask 'why are you like this?' afterward 😑

TL;DR It's a good idea to use microservices for a team of three or four people that only handles one or two microservices. Otherwise, stay away!

Falling in love with Microservices 🥰

I started using the microservice architecture in 2015 when I had to refactory a medium-size Django app into pieces. Since then I have been using microservices for both work and personal projects non-stop.

At first glance microservices are great, it looks like you get a lot of benefits and it makes you think harder about every component of your application.

Microservices - also known as the microservice architecture - is an architectural style that structures an application as a collection of services that are:

Highly maintainable and testable

Loosely coupled

Independently deployable

Organized around business capabilities

Owned by a small team

source: https://microservices.io/

I was very happy with having my multiple repos, big docker-compose.yml files, multiples databases, stitching everything together, and watch my software work, or kind of. But that excitement went away when I had to keep everything working and updating things.

When reality kicks in 😕

Now, after 6 years of experience, I've concluded that microservices are not a good idea when you have a team of ten or fewer people and more than three or four microservices.

In that scenario, your development cycle will suffer and things will become tedious and more time expensive.

The main issue is not the microservices architecture itself, but rather the number of tools, knowledge, and preparation that the team needs have to be able to work properly.

In my experience, the team that I lead experienced the following issues when dealing with microservices:

  • Upgrading frameworks versions was hard because we had to do it for every microservice, build, and deploy.
  • We had a few libraries that were common for all microservices. Every time we discovered a bug or decided to change something, we had to apply that change to every microservice.
  • Changes are part of the product life cycle, and sometimes those changes affected more than one microservice.
  • Debugging was harder because the data flow through applications.
  • Individual database schema for every microservice and restricted access to them forced us to use multiple microservices to be called to obtain a dataset
  • Creating and maintaining a small dump of all databases for dev and QA purposes was HARD!

Today I prefer going with the traditional monolithic architecture, but making sure that my design will allow me to switch to microservices easily.

As a conclusion, I'll (try to) get back to monolithic as a starting point and move to microservices when the team size is large enough and the correlation between team size and microservices is adequate.

Another solution is to create microservices for a small part of the application that could benefit from it.

Fun fact: Although I say this, I did use microservices on my recent side project. Maybe I'm hooked up and need counseling 😂

Top comments (7)

Collapse
 
andreidascalu profile image
Andrei Dascalu

Well, the points you make are certainly valid and for sure microservices (the proper) way may not make sense for any project (or indeed for any team, depending perhaps on size or simply on experience in general).

Speaking from my own experience (as many of these challenges are familiar), I have some observations:

  • upgrading frameworks: only done per service as needed. I see no reason to do it all the time for all services. Usually on our projects we perform maintenance next time we need to touch a service (update framework / dependencies / perhaps some light maintenance)
  • common dependencies: unless it's a security issue, having to update all services that use a dependency on an update should be needed unless there's an all-around refactor / redesign. This can get complicated but once a dependency becomes shared it's critical that a service should be able to function on a tagged stable version of that library otherwise it's a deeper design issue there. Certainly you can't "freestyle"-it as a shared component inside a monolith.
  • debugging: sorry, but here I'm going to defer to what I call the Holy Trinity of microservice projects: logging/tracing/metrics. With OpenTracing embraced by major projects and with support across all languages there's no reason not to instrument your services from the get go. With Tracing in place, debugging becomes easier. With tools like Telepresence, live debugging with a local service is awesome.

There's something to be said about microservices though. In small teams it's hard to go for the proper approach. Between the need to have automated reliable processes in place for everything (DB dumps, for example). But in small teams you can go for an imperfect approach with larger services that could share some things, which is fine when communication lines are small. On the downside, it's not a good practice in the long run but it can be adapted if the team grows.

Also, DevOps. If you don't practice DevOps (in the proper meaning of the term), there's no way to grow into microservice adoption.

Collapse
 
gdi3d profile image
Adriano Galello

Hey, thanks for joining to the converstaion.

Let me reply a couple of points if you don't mind:

upgrading frameworks: Kind of true. You don't need to do it all the time, but sooner or later becomes technical debt and it just pile on top of everything else.

common dependencies: Same as above, it add up at the end.

debugging: I think your point is valid, there's a lot of good tools out there. But I'll argue that the complexity increases and dev cycle is more time expensive when working with a small team handling the whole app (more than three or four microservices). Also the learning curve needs to be taken into account.

The point that I was trying to prove is that, based in my experience, microservices adds complexity and as a team leader/product owner is hard to balance all the aspects of the system if you have a small team.

And just to be clear: I know I could have done things better, at the time I wasn't aware of some problems that I encountered later on, but I learned a lot from mistakes and maybe this could help someone else.

Collapse
 
omrisama profile image
Omri Gabay

What's OpenTracing? Haven't heard

Collapse
 
andreidascalu profile image
Andrei Dascalu

OpenTracing is a standard for defining methods of tracing (data structures, how tracing integrates across protocols, etc). It standardizes how tracing happens and how data is exposed to compatible client applications. Jaeger is a pretty well known CNCF project that implements OpenTracing (so does Zipkin).
opentracing.io/

Collapse
 
omrisama profile image
Omri Gabay

I still haven't really figured out how to test microservices, which is one of the biggest downsides for me.

Collapse
 
gdi3d profile image
Adriano Galello

Test what exactly?

Collapse
 
omrisama profile image
Omri Gabay

Integration and E2E between different microservices.

Individually testing microservices isn't as hard, depending on how you're building them.