Fault tolerance(容错)指的是:系统在部分组件出现故障时,仍能继续提供服务(哪怕是降级的服务),而不是直接整体瘫痪。它的出发点是承认「故障一定会发生」——硬件会坏、网络会断、进程会崩——所以与其指望不出错,不如让系统在出错时还能扛住。
容错与 fail-fast 的关系
这两个概念常被放在一起,但取向不同,而且并不矛盾:
- fail-fast(快速失败):一检测到不该出现的状态就立即、显眼地失败,把错误暴露在离源头最近的地方。
- fault tolerance(容错):出错时尽量不让整个系统垮掉,通过冗余、隔离、降级等手段继续提供服务。
实际系统往往两者同时用、用在不同层面:单个组件内部对非法状态 fail-fast(尽早抛错、不带病运行),而系统整体对组件级故障容错(一个实例挂了还有别的顶上)。换句话说,「让局部快速失败」恰恰是「让整体可容错」的前提——故障被快速隔离出来,才不会扩散成全局问题。
常见的容错手段
容错不是单一技术,而是一组配合使用的做法:
- 冗余 / 副本(redundancy / replication):关键组件多部署几份,单点坏了还有备份。是容错的基础。
- 失效转移(failover):主组件故障时自动切到备用组件,对外尽量无感。
- 优雅降级(graceful degradation):非核心功能出问题时,关掉或简化它,保住核心链路,而不是整体报错。
- 重试与超时(retry / timeout):对偶发、可恢复的失败(网络抖动等)做有限重试,并用超时避免无限等待。
- 熔断与隔离(circuit breaker / bulkhead):下游故障时快速失败、暂时切断调用,防止故障沿调用链扩散、拖垮上游;用隔离把故障限制在局部。
- 拜占庭容错(BFT):更强的一类容错,能在部分节点发送错误甚至恶意信息时仍达成一致,多见于分布式共识、区块链。
微服务语境下的「服务容错」(熔断、隔离、限流、降级、超时)可参考 微服务 一文;Actor 模型的「任其崩溃(let it crash)」则是另一种思路——不在每处做防御式校验,而是让监督者在崩溃后重建。
容错 ≠ 高可用,但服务于它
容错是手段,高可用(high availability)是目标之一。通过容错让单点故障不影响整体服务,正是为了达成更高的可用性(更短的中断、更小的影响范围)。衡量容错切换效果常用的 RTO / RPO,见 failover。
边界:容错不是无限兜底
- 容错有成本:冗余要多花机器,复制要付出一致性 / 性能代价(参见 CAP 里 C 与 A 的取舍)。不是所有系统都需要、也不是所有故障都值得容错。
- 别把错误吞掉:容错是「继续提供服务」,不是「假装没出错」。被容错处理掉的故障仍要记录、告警、可观测,否则就成了「静默失败」——问题被盖住、没人知道,反而更糟。
- 区分该容忍的和该暴露的:对可预期、可恢复的外部故障(网络、下游不可用)做容错;对「程序员的错误 / 不该发生的内部状态」则应 fail-fast,越早暴露越好。
一句话:fault tolerance 关心「出错时系统还能不能用」,靠的是冗余、隔离、降级这些手段把故障的影响范围压下去;它和 fail-fast「尽早暴露错误」在不同层面配合,共同支撑系统的可用性。