Breaking data structures apart often leads to it's own form of spaghetti.
I can say this based on four years working on a large multi-tenant service platform composed of several hundred microservices, held against a background of 24 years building software systems, including multi-million-line monoliths (good and bad).
If you're a small company, should you start with a microservices architecture? No. It is much harder to operate. Should you factor your monolith so it is easy to transition to microservices later? Yes. Your monolith will be of higher quality for doing so.
I'm not against micro-services, I'm against making everything a microservice because one can.
It's also an architecture that is now much more prone to failures, because while procedure calls essentially never fail, RPCs do. Or if they don't fail outright, have unpredictable latencies etc.
(I turned a microservices/SOA code-base into monolith back in 2003/2004. It worked wonders.)
This can also introduce big problems with 95th-percentile latency, because the retries aren't free, they trade failure for slowness. In user-facing services this often isn't a problem, because the user eats the slowness and grumbles. But in services way down in the stack (eg. BigTable), it can be a big problem. High 95th-percentile latency can make services that previously weren't on the critical path suddenly part of the critical path; it can trigger timeouts in higher-level code; it can trigger retries in higher-level code; and it can cause large increases in load (with the possibility of further cascading failures) if those additional retries put some other service over its capacity limits.
TANSTAAFL. RPC failures still result in complexity, it's just that there are possible systems that can shunt that complexity into where it's less of a problem for the user. The only time you can outright ignore them is if you're a junior developer, though; anyone at senior/TL/architect level needs to think about them and be prepared.
Hmm...
1. Software applications are written with little error-handling on networking errors. During a network outage, such applications may stall or infinitely wait for an answer packet, permanently consuming memory or other resources. When the failed network becomes available, those applications may also fail to retry any stalled operations or require a (manual) restart.
https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...
Infinite retries aren't "not really a problem". If the server isn't there or can't be reached, it isn't there or can't be reached. This is not a problem software/infrastructure can paper over transparently. You can try your best to mitigate, but that's hard, and often makes things worse.
I remember a colleague trying out CouchDB. His takeaway was that all error-recovery attempts by distributed CouchDB servers made things worse. So you could use it as a semi-decent single-instance DB, but mercy on your soul should you be so brazen as to attempt to use the distribution features.
> heavy investment in microservice tooling.
And what percentage of microservices is that?
> costs in terms of infrastructure and latency
>> Or if they don't fail outright, have unpredictable latencies
Hmm...
Given the choice, I'd rather re-write 50 microservices in a heartbeat.
It's a function of people and constraints.
Or look at it this way: Even if monoliths are the problem, well, the people wrote the monoliths...
You are doing the same thing OP did: Fundamentally misunderstanding the purpose of programming. It's an interface for humans to communicate with machines in a way that makes sense to humans.
If monoliths always end up being unmaintainable pieces of garbage, then monoliths aren't really designed for humans or our tendencies. That means monoliths are the problem... they don't adapt to human nature.
1) You have tooling.
2) Probably also shared conventions and libraries.
3) Everything is easy to find and run on single dev machine.
And no, monoliths almost never end up that way as long as they're internally modular. Services are just modules with less sharing and more overhead.
How many monolithic 1,000,000+ line code basis have you navigated.
1) That's true of both. 2) That can be true or false of both. 3) That's covered by tooling?
> And no, monoliths almost never end up that way as long as they're internally modular.
Well your caveat is literally the problem this post is discussing. They usually aren't.
You don't have to prove to me that monoliths are bad. I get it. (You don't have to prove to me that spaghetti is bad, either.) But you seem to have missed my point.
Monoliths don't just happen. They didn't just wind up in your server room because the roof leaked during rainy season. They didn't get delivered by FedEx by mistake, and your people went ahead and signed for them. No, the monoliths are there because people wrote them.
Why did people write them? 1. Because they didn't know better, and just fell into it. 2. Because they thought that was the best way to architect something. 3. Because they didn't take the time and effort to make something more modular.
People cause the monoliths. To fix monoliths, you have to fix the people problem, or you're going to continue to get monoliths.
Programming is for people. I can count on zero hands how many times I've seen monoliths not end up... globbed together. It's fundamental to humans to like things broken up into little pieces with boundaries.
If monoliths don't work for people, then monoliths are the problem.