Day30-10|9.4.1 容错设计技术:让系统在故障发生时仍能提供正确或可接受的服务

一、教材定位

容错设计是软件可靠性设计的重要组成部分,目标是在一个或多个部件发生故障时,系统能够继续提供全部或部分正确服务,或者以受控方式降级、恢复和补偿。容错不是让系统永远不发生故障,而是控制故障影响,阻止错误传播,保证关键业务结果,并尽快恢复正常状态。

二、容错的基本思想

容错通常包含故障检测、故障隔离、故障屏蔽、服务降级、故障切换、状态恢复和业务补偿等环节。可靠的容错方案必须回答:发生了什么故障,系统如何发现,故障影响谁,哪些服务仍可用,数据如何处理,用户看到什么,恢复后如何验证。

可以用以下链条理解:

故障发生 → 检测与定位 → 隔离影响 → 选择继续、切换或降级 → 恢复状态 → 校验数据 → 补偿业务 → 复盘改进。

如果只有重试而没有幂等,可能造成重复操作;只有切换而没有数据同步,可能造成状态丢失;只有降级而没有恢复,系统可能长期处于不完整状态。

三、冗余技术

冗余是通过增加备用资源降低单点故障影响,包括硬件冗余、进程冗余、节点冗余、网络冗余、存储冗余、数据冗余和服务冗余。

1. 主备

主备结构由主实例提供服务,备用实例在主实例故障时接管。它实现较简单,但需要处理健康检查、切换条件、状态同步、脑裂、未完成请求和恢复后的数据校验。热备可以快速接管,冷备成本较低但恢复时间较长。

2. 双活和多活

多个实例同时提供服务,可以提高容量和区域可用性,但会带来数据一致性、请求路由、冲突处理和运维复杂度。多活不是所有业务都适合,强一致交易通常需要按业务分区、单元化或权威区域管理。

3. N+1 和集群

N+1 通过额外容量承受一个实例故障,集群通过负载均衡和健康检查分配请求。设计时要确认均衡器、注册中心、配置和存储是否仍然是单点。

四、故障检测技术

容错的前提是能够及时发现故障。检测方式包括心跳、健康检查、超时、错误率、资源阈值、业务探针、数据校验和异常事件。

单纯检查进程存活不足以说明服务健康。健康检查可以分为存活检查、就绪检查和业务检查:存活检查判断进程是否存在,就绪检查判断实例能否接收流量,业务检查判断关键依赖和功能是否正常。检测过于敏感会造成误切换,过于迟钝会延长故障影响,应通过阈值、连续次数和滑动窗口减少误判。

五、故障隔离技术

故障隔离可以防止局部问题扩散。常见技术包括舱壁隔离、线程池隔离、连接池隔离、租户隔离、进程隔离、服务隔离、数据分区和故障域隔离。

例如一个外部接口变慢时,如果所有业务共享同一连接池和线程池,慢请求会占满资源,导致其他功能也不可用;通过独立资源池、超时、限流和熔断,可以把故障限制在受影响的业务范围内。隔离会增加资源和运维成本,需要根据业务重要性分级。

六、屏蔽和降级技术

故障屏蔽通过冗余、默认值、缓存、校验和投票隐藏部分故障,使上层继续获得可接受结果。降级是在资源不足或依赖故障时关闭非核心能力,保护核心流程。

降级必须提前设计,明确哪些功能可关闭、用户如何感知、数据如何补偿、恢复后如何恢复。查询可以返回缓存或简化结果,推荐可以暂时关闭,通知可以异步重试,但支付状态和账务结果不能用不可靠的默认值代替。

七、超时、重试和熔断

超时限制请求占用资源的最长时间,避免调用链无限等待。超时应按业务和下游能力设置,不能所有接口使用同一个固定值。重试适合短暂网络故障、连接瞬断等可恢复错误,应使用次数限制、指数退避、随机抖动和幂等控制。

熔断在错误率或超时达到阈值时暂时停止调用故障依赖,保护调用方和下游。熔断通常包括关闭、打开和半开状态。半开阶段通过少量探测请求判断依赖是否恢复。熔断后必须有降级或补偿路径,否则只是把错误快速返回。

八、幂等和去重

幂等保证同一业务请求执行一次或多次,最终结果相同,是重试、消息投递和故障恢复的重要基础。实现方式包括业务唯一键、请求号、状态检查、去重表、幂等令牌和版本条件更新。

幂等不是简单给接口加一个ID字段。要明确唯一键的范围、保存周期、并发竞争、成功和失败状态、超时后的查询以及数据清理。支付、下单、库存扣减和消息消费都应根据业务语义设计幂等。

九、事务、补偿和恢复

分布式流程中,局部成功和局部失败很常见。事务可以保证局部原子性,补偿可以处理跨服务或跨系统的最终一致。补偿不是简单重试,应根据业务状态执行反向操作、人工审核、对账或重新发起。

恢复设计包括状态持久化、日志重放、备份恢复、检查点、断点续传和回滚。恢复后要校验数据、缓存、消息、索引和审计,避免系统虽然上线但业务状态错误。

十、容错设计的代价与边界

容错会增加副本、资源、代码、配置、测试和运维复杂度。过度重试可能造成雪崩,过度降级可能让系统失去核心价值,过度冗余可能造成一致性冲突,复杂补偿可能形成难以维护的状态机。

因此容错要分级:关键交易优先保证正确性和数据完整,一般查询可以降级,非核心通知可以延迟,低价值功能可以暂时关闭。架构师要明确哪些故障必须自动处理,哪些故障需要人工介入,哪些数据绝不能丢失。

十一、案例分析:库存扣减容错设计

某电商平台在促销期间出现库存超卖。原因包括重复请求、消息重复、库存数据库短暂超时和服务重试无上限。改造后,订单请求使用业务幂等键,库存服务拥有库存数据并通过条件更新扣减;数据库超时采用有限重试和退避,超过阈值后进入待处理状态;消息消费记录事件ID,重复消息直接返回已处理结果;库存服务按商品分区隔离,热点商品采用队列削峰;库存差异通过定时对账和人工补偿处理。

系统还设计了降级:推荐、评论和非关键通知在高峰期关闭,查询服务读取缓存,但实际扣减必须经过库存权威服务。通过重复下单、消息重复、数据库延迟、节点故障和恢复后对账测试验证容错策略。

十二、练习题

题1

容错设计通常包括哪些基本环节?

参考答案

故障检测、故障隔离、故障屏蔽、降级、切换、状态恢复、数据校验和业务补偿。不同系统还需要结合冗余、超时、重试、熔断、幂等和备份。

题2

为什么重试必须与幂等结合?

参考答案

网络超时并不代表业务没有执行,盲目重试可能导致重复扣款、重复下单或重复扣库存。幂等可以保证重复请求最终结果一致,重试还应限制次数、退避并区分暂时错误和永久错误。

题3

为什么降级不能使用同一种策略处理所有业务?

参考答案

不同业务的正确性和损失边界不同。查询可以返回缓存,推荐可以关闭,通知可以延迟,但支付、账务和库存不能用不可靠的默认值替代,必须进入待确认、补偿或人工处理流程。

十三、论文写作素材

论文中可写“项目基于故障模型设计容错体系:使用冗余和健康检查处理节点故障,使用超时、重试、熔断和舱壁隔离控制依赖故障,使用幂等、状态机、消息去重和补偿保证业务正确,使用降级和限流保护核心流程,使用备份、日志和对账支持恢复。通过故障注入、重复请求、网络延迟和数据库切换测试验证,并明确容错措施的成本和业务边界。”

十四、今日复盘

容错策略必须与故障模型、业务优先级和可观测性结合,只有经过故障注入、恢复演练和业务校验,才可以证明设计真正有效。 可验证。 并可复盘。

容错设计的主线是检测、隔离、继续或降级、恢复、校验和补偿。掌握冗余、超时、重试、熔断、舱壁、幂等、事务、补偿和恢复的适用条件,记住容错不是无限重试或简单集群,核心目标是控制故障影响并保证业务结果正确。