微服务与“单点故障”概念:多服务架构为何优于单体架构?
Great question—this is a super common point of confusion when transitioning from monolithic architectures to distributed systems, especially with linear data flows like your A ===> B ===> C pipeline. Let’s break this down step by step.
First: Why does service B exist if the system can’t run without it?
Service B isn’t just arbitrary—it’s there to handle a specific, focused responsibility that makes the overall system more robust. For example:
- Maybe A collects raw order data, B validates that data (checks for valid inventory, correct customer details, or fraud red flags), and C processes the payment.
- Without B, C would be flooded with invalid or risky requests, leading to failed transactions, compliance issues, or even crashing C from overload.
- B’s job is to do one thing well, which makes it easier to maintain, update, and debug than if that logic was tangled up with A or C’s code.
Now: How does splitting into A/B/C differ from a monolithic ABC?
Even if your pipeline is linear and a single service outage breaks the workflow, the distributed approach still offers critical advantages over a monolith:
1. Granular fault isolation (not total elimination)
In a monolith, if B’s code crashes (say, a memory leak or a bad database query), the entire ABC process goes down. A stops accepting requests, C stops processing—everything is dead.
In your distributed setup:
- A can keep running, storing incoming requests in a message queue instead of dropping them.
- C can keep processing any backlog of messages it already has, or idle gracefully until B comes back.
- Only B is down, not the entire system. You can restart or scale B independently without touching A or C.
2. Independent deployment and scaling
- Need to update B’s validation logic? In a monolith, you have to deploy the entire ABC codebase, taking the whole system offline (or dealing with complex rolling deployments). In distributed systems, you can deploy just B—A and C keep running without interruption.
- If B is the bottleneck (e.g., validation takes longer during peak hours), you can spin up extra instances of B to handle load. In a monolith, you’d have to scale the entire ABC app, wasting resources on overprovisioning A and C.
3. Flexible technology choices
- A could be built with Python for easy rapid development of user-facing order collection.
- B could use Go for high-performance, low-latency validation.
- C could use Java because it has mature, compliant libraries for credit card processing.
A monolith forces you to pick one tech stack for everything, limiting your ability to use the best tool for each job.
4. Easier debugging and observability
- If B starts throwing errors, you can monitor its metrics (throughput, error rates, latency) independently. You don’t have to sift through a single monolithic log file to find where the problem is.
- You can add circuit breakers to B: if it’s down, A can temporarily return a "system busy, please try again later" message instead of letting requests pile up and cause cascading issues. In a monolith, this kind of targeted resilience is much harder to implement.
A final note on "single points of failure"
Distributed systems don’t eliminate single points of failure entirely—if C is your only credit card processing service, it’s still a single point of failure. But they make those failures less impactful and faster to recover from:
- You can cluster C (run multiple instances) to avoid a single outage taking down payment processing.
- You can add fallback logic (e.g., a secondary payment processor) to C without touching A or B.
In short, splitting into services isn’t about avoiding all outages—it’s about making those outages manageable, reducing downtime, and making your system easier to evolve over time.
内容的提问来源于stack exchange,提问作者Mike Rowe Servis

