I'm just curious to know, when you said "the easiest and most sensible thing to do is chunk out large parts of the project and put them aside as a microservice" ... were these chunks separately deployable units for external "public" use.
I'm just curious to know, when you said "the easiest and most sensible thing to do is chunk out large parts of the project and put them aside as a microservice" ... were these chunks separately deployable units for external "public" use.
Microservices actually make you encapsulate your code, at least within the microservices, because you can't call out to it directly. They don't necessarily force you to implement the single responsibility principle, but they do a good job of pushing you. Microservices implement a service-locator pattern through DNS or web routing, one form of the dependency inversion principle. Microservices make you pass data around as entities, instead of Active Record instances.
The price for this sort of thing is very steep, though; distributed systems are inherently icky, harder to trace, and more prone to failure, and besides this, you've added network overhead to each service call.
I wish more engineering teams would consider spending half the effort of microservices on simply disciplining their monoliths. They might get somewhere...
In my experience, if your services are developed by the same people, and not separated by teams, engineers will often tightly couple the services with fragile and opaque dependent changes regardless.
While in monolith this is painful, at least you have a complete stack trace and the ability to run things through a step debugger you orient yourself. In a distributed system tribal knowledge tends to be your only savior.
When we design systems, we need to spend more time thinking about what is most likely to happen as opposed to what we feel should happen.
100%. This is an uphill battle, though. I've encountered so many engineers who equate "real engineering" with "building giant machines." You just can't convince them otherwise.
I've watched people build giant, real-time stream processing pipelines compromising tons of moving pieces (lambda, sqs, s3, sns, stepFunctions, etc..) to build... a reporting table, and all for... 1.3gb of data. Literally.
Ultimately, despite the "sell," I don't think microservices as a forcing function for good practices works in practice. If the team lacks the skills to build a disciplined monolith, then they 100% lack the skills to build a distributed one.
There is this trend in technology - every few years everyone changes their minds about everything:
* 2012 - sql is the best.
* 2016 - sql sucks, nosql is the future
* 2020 - nosql suck, sql is the best.
* 2024 - {fill in the blank}.
The same thing is happening with microservices. But in addition docker, kubernetes and recently unikernels have joined the party. The concept is the same though.
What I am trying to say is that either of those can be good or bad in different scenarios. It's a question of picking the most appropriate one for the situation.
Sun RPC, CORBA, DCE, DCOM, XML-RPC, SOAP, REST, gRPC,....
You need to be disciplined to keep a monolith highly modularized. For microservices, in contrast, their architecture encourages modularization.