Link Search Menu Expand Document

Grinding the monolith

Monolith

Pros:

  • Easier to deploy
  • Easier to place and find stuff in

Microservices

Cons:

  • Operational complexity
  • Partial failure

Pros:

  • Independence of development
  • Independence of scalability
  • Building in smaller and simpler pieces

We have heard the story before

Java Beans, COMM, COBRA

  • Independent components, you can just buy and connectcomponents
  • Decoupled and simple pieces

We can have software that works like Lego. But this hypothesis does not work in reality as there are many more dimensions (connections between components). Components may have hundreds or thousands of collaborators, we would need to have to have nth dimensional Lego bricks!

Maybe a better model would be Mycelium, a fungus where fractal roots communicate to each other in a way more complex way.

We can try to make a clear horizontal layered separation: UI, Application, Domain, Persistence. Try to repeat the pattern in vertical separations, but soon enough they will start coupling each other. We can make the thing even worse with operational monitoring, logging, etc.

Maybe the Layers architecture referred more to protocol stacks than to web applications, precisely because of the standarisation of interfaces between layers does not generally apply.

Microservices

The key issue is around safety for different teams to operate independently. Issues from other teams should affect yours. Without this, you’ll start adding checks, reviews, etc. “The Fear Cycle”.

Safety failure in Monoliths

  • Bad code has an unlimited span of effect (SQL leak will affect all code)
  • Modifying shared code will affect other teams
  • Semantic coupling, different concepts mixed under the same name. What works for one context, may not work for the other

All those make code changes slow. Many teams tried transformations towards microservices, 2/3s failed because impatience, unrealistic expectations, or hubris.

Strategies to move towards microservices

Clean then separate

Refactor to create interfaces between subdomains, then turn those into HTTP interfaces.

Failed

  • You have to stop feature development
  • You have the clean team is going slower than the feature teams that will make compromises to go faster (their work is throwaway)

Entity services

You turn your key domain objects into services

Failed

  • Transactionality problems. Microservices need to have behaviour
  • Deployments are painful as redeploying a core entity service will affect a lot of clients
  • Distributed monolith

Project teams

Have a pool of people (contractors) do create services and throw them back to the pool once they finish.

Failed

  • Favour deadlines (short term) over high quality code and architecture initiatives (long term)
  • If you done your hard work, you should enjoy the fruit of the result. If not, you should leave with it and learn from it
  • Better to have product teams (which can have projects)

Clean-sheet design of a new services

Create new services from scratch

Failed

  • We make the same mistakes over and over
  • This system will always lag behind
  • Optimism not supported by past evidence. What happened last time (unexpected issues) is most likely to happen this time

The strangler

Intercept traffic to the existing system and replace pieces with new services. It is a transitional pattern.

Partial success

Clone and slash

Clone the monolith for each team. Remove the code the team does not need. Transitional state. You will be sharing the DB for a long time.

Success

Continual redesign/rebuild

Keep the presure on to keep redesigning, microservices are never done. Remove code and microservices, which is one of the main benefits of removing microservices.

Success

Microservices by lifecycle

Each stage of the process has its own microservice, and each process/microservice passes the state to the next.

Success

Transmit domain objects on the wire

Domain objects as the representation to transfer in APIs.

Failure

  • Domain object coupled with the API, will be very difficult to evolve and change
  • Makes it very difficult to handle multiple versions of APIs
  • Leaks implementation details and internals of the service

Turn domain objects into hashmaps, lists, etc.

Refactor to hexagons

Express the domain independently from integration and persistence implementation details.

Success


Think long-term, act short-term. Solve the problem in front of you.


References