I’m often confronted with the question if microservices are a good idea or if a monolothic approach is better. My opinion: Neither is the best way to design software. Why? Let’s take a look at how the two architectural types are defined:
Microservices: Every microservice only serves exactly one purpose. When we talk about something like a user management in a support portal then you would need one service for user creation, one for user updating, one for user query, one for authentication, and so on and so forth. And I’m not even talking about the part where questions are posted and then they are answered by somebody.
Monolith: Everything is one big pile of multiple purposes stitched together. I have everything in one. The user management, the portal itself, maybe some automation for default answers, the UI, everything.
Imagine we now have a problem with the automation for default answers. There is a memleak which causes after some time that the automation crashes. With microservices only this part crashes and that’s it. Everything else is fine. With a monolith you now have a problem. But is this the only argument that matters when we decide to go with microservices. Honestly: NO! We also have to consider other aspects when it comes to that:
- Connection between services
- Latency
- Are the other microservices ready for another service being (temporarily) offline
- Do I need to lock data? How?
And another question arises there: Is it really worth the additional effort to break things into such small parts?
Now here’s my shot against microservices. As stated a microservice only fulfills one purpose. But I think this is problematic. Let’s come back to the user management. Imagine the following scenario: The “User Update Service” updates a user, but at the same time the “User Deletion Service” deletes that user. I know that’s a weak example, but with this simple scenario we see that we need locks, we need a fast connection between the two services to maintain that lock and even though the user update might be useless anyway because it will be deleted anyway we do not know what the update was now. The worst case is that the user update consisted of a “prevent deletion” flag. Now what?
And also my shot against monoliths. The same scenario would have been less problematic in a monolith, but here we can not only look at this scenario because here we usually have much more going on in just one service. The delete service might exhaust a thread pool or whatever and the whole thing is down.
So my suggestion is to not have a microservice architecture, but a service architecture. Services have a purpose, but not a single little operation, but an area what it operates on. Let’s have a user management service which does all the stuff related to users (create, update, delete, authenticate) and another service handling questions and answers. Important here: Have a stable API. Although you only have a small set of bigger services,W you already have a framework for handling remote services. Cool thing about that: You can take parts of services and transform it into separate ones if needed. E.g. the authentication part of the user service is most important and needs scaling etc: Rip it out of the user management service.
Oh and there it was: The word “scaling”. Is it easier to scale a microservice or a monolith? But what about a service which serves multiple operations of an area?
The bottomline of this whole post is basically: Think about what your software needs to do and how reliable it has to work. Usually there are multiple ways how to achieve a goal. The one approach is to hop on the hype-train (microservices FTW) or go the old approach with monoliths. In my opinion a hybrid approach is the way to go in most applications. Even though you do not start with small services it makes it easier to rip out parts of functionality which are problematic (business critical) or need scaling (because of a very dynamic number of requests, etc).