Wednesday, September 19, 2018

The distributed monolith antipattern


The words distributed and monolith are usually adversaries in software architecture, contrary to the monolith model,  a distributed approach will allow you to have isolated services as building blocks of functionality for your system. Let's assume you reached that architecture already, either from scratch or by decomposing an existing monolith. At this point you have a set of services. 



Some people go and just say - "it's microservices!". Well..., that's not enough yet, but now you have all the pieces into individual services and the whole system working together.  This is a step into the right direction for scalability, but we can do more in other areas. 

So, let's check: how do you deploy them?

If you deploy all services at once, you still have a lot to improve, for now you have a "distributed monolith" (Open to a better name for this), which I consider to be an antipattern, and this is more of a common practice than expected, this is basically a problem inherited from Service Oriented Architecture but there are a few reasons it happens.

Common reasons


1. Services share the same database.
This is old as time, it's OK for this to happen during transition from monolith or classic SOA to microservices, but you need to move away from it. Sometimes organizations just don't pour resources to continue moving forward with the evolution of a system.

2. Deployment constraints tying them together
Some DevOps limitation, rule or result of laziness (e.g. somebody liked how things looked in one docker compose file and left it like that).  

3. Shared library with business logic
Another bad practice from SOA, a developer encapsulated business logic into a library, then new business updates require all apps and services to be updated and deployed almost simultaneously.  Reusability is important in software but doing it through libraries when using services is a Pandora's box. If you have a service-based architecture, expose business logic only through services.  


Notes.
You can find almost any reason to justify what could be seen as a bad practice, it's up to you, the developer, to decide how to proceed. For example, sometimes you *have* to share a database because consistency is more important than speed or scalability for a specific application. If a requirement like that exists, then you are already building the correct system and there is no need to modify it just to fit with an architectural schema.