智汇 IT
城启新篇

高可用架构的故障域设计踩坑实录

上周帮朋友的电商团队复盘大促故障,拍桌子的声音现在还能想起来。

他们之前为了做容灾,特意在两个可用区开了三套订单服务实例,三副本配置中心,数据库也做了主从跨区同步,看起来架构图画得漂漂亮亮,评审的时候全票通过。结果大促当天其中一个可用区的机柜供电波动,直接把整个订单链路打崩了,半小时少了两百多万流水。

我当时听他们讲完整个故障过程,差点把手里的奶茶喷出来——合着你们花了几十万做的跨区容灾,所有核心依赖都挤在同一个供电环里?

你以为的跨区部署根本不是隔离

很多人对故障域的误解,从画架构图的那一刻就开始了。

说白了,故障域是指「一旦某个底层资源出问题,会同时影响到的所有业务资源的集合」。不是你在架构图上用两种不同颜色的块画两个可用区,就算做了隔离。你得抠到最细的粒度:供电回路、物理机柜、核心交换机、运营商出口,甚至云厂商底层的某个集群节点,都可能是一个独立的故障域。

那个电商团队的问题就出在这:他们以为把订单服务的实例分到两个可用区就够了,结果所有订单实例的配置中心,都连的同一个可用区的Nacos集群,而Nacos的三个副本,刚好都放在出问题的那个机柜里。供电一波动,Nacos全挂,订单服务拿不到最新的配置,直接报错重试,把数据库打满,整个链路直接雪崩。

跨可用区部署故障域重叠示意图
跨可用区部署故障域重叠示意图

拆分故障域最容易踩的隐形坑

不过话说回来,就算你把业务实例拆到了不同的故障域,坑也远没填完。

我见过最离谱的一个团队,为了容灾特意在两家不同的云厂商开了实例,结果两家云的BGP回源线路都走同一个骨干网节点,上次骨干节点被施工队挖断,两家一起挂,客户打电话来骂的时候运维都傻了。真的。

还有的团队把数据库的只读副本拆到了不同的可用区,结果所有副本都挂在同一个物理存储池上,存储池一坏,所有副本同时失联,连个备份都找不到。

这些坑的共同点就是,你只盯着自己能控制的业务层做拆分,完全没考虑底层依赖的故障域是不是重叠了。

微服务依赖链路故障域拆分对照表
微服务依赖链路故障域拆分对照表

不用上重武器也能落地的拆分方法

说实话,故障域设计根本不需要你一上来就砸几千万搞全球多活。大部分中小团队的业务,只要把核心链路的故障域拆明白,足够扛住90%的常见故障。

先从最核心的链路摸起,比如订单、支付、库存这几个核心模块,把每个依赖的物理边界列出来:在哪个可用区,哪个机柜,走的哪个网络出口,甚至连对应的供电回路号都要标清楚。别嫌麻烦,这些东西你现在不摸清楚,下次出故障还是抓瞎。

用K8s的团队更简单,直接给核心服务的pod加反亲和规则,指定按机柜、按可用区打散,不用改一行业务代码,就能把副本的故障域先拆出来。配置中心、数据库这些中间件也一样,别把所有副本堆在同一个机柜里,每个故障域最多放一个副本,出问题的时候不会全挂。

拆完之后一定要做验证。别觉得你架构图画得好就没问题,直接上混沌工程,随便掐一个可用区的网络,断一个机柜的电,看看业务能不能扛住。那个电商团队复盘完之后,做的第一次混沌测试,直接把Nacos所在的可用区网络全掐了,结果订单服务直接连不上配置中心,才发现他们之前的Nacos集群根本没跨区部署,之前评审的时候全是拍脑袋说的跨区,白折腾了大半年。

还有个最关键的边界:不是所有服务都需要拆分故障域。那种非核心的埋点、后台管理、甚至是用户评价服务,就算全挂了也不影响核心交易,没必要花精力给它们做冗余。把钱和人力都砸在核心链路上,性价比才最高。

上周那个团队按照这个方法拆完之后,这周压测,随便掐一个可用区的流量,订单链路的错误率连0.1%都不到。他们之前还担心拆故障域会增加成本,结果算下来,只是把之前浪费在非核心服务上的冗余资源挪到了核心链路上,总预算一分没加。

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:高可用架构的故障域设计踩坑实录
文章链接:https://www.itcdj.com/it/391.html