5 ms·
> I disagree. Starting with a bad set of microservices can be fixed by merging. Merging two codebases is trivial compared to splitting. Again, if I have isolati
by infamia 4y ago
> I disagree. Starting with a bad set of microservices can be fixed by merging. Merging two codebases is trivial compared to splitting. Again, if I have isolation between the services, even if the slicing up was done badly, even if they're coupled, I can just remove the layer between them.
There is still coupling in microservices, it has just shifted to messaging, networking, and queuing. If you get any of those parts wrong, you have a worse mess to untangle with less mature debugging/logging tooling than a monolith enjoys, all the while likely dealing with eventual consistency (depending on the design). I'm not saying don't start with a microservice, but it likely wouldn't be the very first tool I would reach for when starting out if a monolith would do the job effectively. Most things will never be hyperscale and won't benefit from the increased concurrency. You can go a very long way with a "majestic monolith" and a bit of care.
- atx42 4y agoI disagree. If you are able to merge them you spent the work to originally have them split. So more work to start with microservices. It goes back to agile, the easy solution is have a monolith and figure out later how it can be well-split.
- staticassertion 4y ago> There is still coupling in microservices, it has just shifted to messaging, networking, and queuing. Sure, in the sense that your service is "coupled" to a queue and if you don't abstract that away it's hard to change that queue implementation. But in the sense of two services you wrote being coupled, they aren't, in terms of shared state. That gets pulled out. There is no way for one service to mutate the memory of another - it has to send a message to it. That can be TCP or it can be over some queue or stream or whatever. > If you get any of those parts wrong, you have a worse mess to untangle with less mature debugging/logging tooling than a monolith enjoys This is the case with any concurrent system. The fact that so many languages lack concurrency primitives is probably why people don't run into this more often. If you use concurrency primitives in your language, you already have this. > all the while likely dealing with eventual consistency (depending on the design) There's nothing eventually consistent about this system. It fundamentally has causal consistency (since messages from a service must come after messages to that service that triggered them), and it's perfectly capable of leveraging transactions. > I'm not saying don't start with a microservice, but it likely wouldn't be the very first tool I would reach for when starting out if a monolith would do the job effectively. To each their own. I much prefer it. It's far simpler to maintain "good" design since the network boundary creates a hard line in the sand that you physically can not violate.
- blowski 4y ago> That gets pulled out. There is no way for one service to mutate the memory of another - it has to send a message to it. If it’s well-designed, and that’s a big if. Most implementations I’ve worked with constantly mutate each others’s state.
- staticassertion 4y agoNo, it's physically impossible. You have causal consistency across services, not within services. https://youtu.be/lKXe3HUG2l4?t=1438 https://youtu.be/lKXe3HUG2l4?t=1438
- blowski 4y agoCodebase A writes data to datastore. Codebase B mutates it. Codebase A loads it back in, assuming it’s still the same. Boom. You’ve mutated codebase A’s memory.
- staticassertion 4y agoI would hope it's obvious that you haven't mutated A's memory, but I'll just suggest you watch the talk.
- blowski 4y agoFor all intents and purposes, you’ve mutated the memory. Sure, you haven’t mutated by reaching directly to the RAM. But the effect is still the same.
- nicoburns 4y agoHow is that any different to calling a function on a class? That's technically not class A modifying class B's memory either. B modifies it's own memory in response to a message (function parameters) from A. The message going over a network doesn't make that fundamentally different.