首页 / m.itcdj.com / 正文

高可用架构的故障域设计落地手记

去年双十一凌晨三点,我在公司楼下的鸭血粉丝汤店里攥着手机,群里炸了。

当时我们的订单服务花了三个月做了多可用区改造,三个副本分别部署在华东1的三个可用区,每次发版都要走三次灰度流程,运维团队还专门做了自动调度策略,保证每个可用区的实例数不低于总规模的三分之一。所有人都觉得这次肯定稳了,结果零点流量刚冲上来,三个可用区同时告警,订单接口响应时间直接飙到10秒以上,半小时里丢了近十万笔订单。

后来查原因才知道,云厂商这三个可用区的核心环网交换机,用的是同一批次的固件,存在峰值流量下的内存泄漏bug,一到峰值全挂。运营部的姑娘后来算的损失,够我们团队吃三年鸭血粉丝汤加煎蛋。

你以为的多副本,可能根本没跨故障域

别听那些架构白皮书扯得玄乎,说白了,故障域就是“某个东西挂了,会连带搞坏多少服务”的范围。

我们当时踩的最大的坑,就是把云控制台给的可用区划分,当成了天然的故障域边界。总觉得三个可用区物理隔离,放进去的服务就肯定不会一起挂,没人去扒过底层的网络拓扑、电力供应、甚至云厂商的运维批次到底是不是共享的。

多可用区故障域划分示意图

说穿了,你看到的可用区只是云厂商给你画的逻辑隔离边界,不是物理层面完全无共享的故障域。举个最简单的例子,你租的三个可用区的服务器,可能都在同一个数据中心园区里,用的是同一路市电,要是园区主电断了,三个可用区照样一起歇菜。更别说我们遇到的这种,底层网络设备用了同一批次有bug的固件,这种藏在地下的共享依赖,你不主动去挖,根本发现不了。

当时云厂商的售后工程师打电话过来道歉,说这个批次的bug他们还在排查,我差点把手里的粉丝汤洒他电话上。

别把故障域划得太粗,也别抠得太细

故障恢复之后,团队里走了两个极端。有人说要把每个服务的实例都拆到每个机架、每个电力分区、甚至每台交换机下面,恨不得每个服务器单独划一个故障域。还有人说反正多可用区也不靠谱,干脆把所有服务都收回来,放在自己租的机房里管。

两种都蠢。

真按第一种来,调度系统直接崩,每次发版光调整实例位置就要花俩小时,内部的OA系统挂半小时都没人管,犯不上花那个运维成本。第二种更扯,自己建机房的成本,够我们再吃十年鸭血粉丝汤。

我们后来摸索出来的规则很简单:故障域的划分粒度,完全绑定对应业务的故障容忍度。核心链路的订单、支付服务,就要拆到跨电力分区、跨交换机批次、甚至跨云厂商的运维集群级别,哪怕多花一倍的调度成本也值。内部用的报表、OA系统,只要跨两个可用区就够了,没必要抠到机架级。

核心业务链路故障域分层划分图
核心业务链路故障域分层划分图

说白了,高可用从来不是无成本的,你要给多大的业务兜底,就花多大的成本去拆故障域,别搞一刀切。

别等故障发生了才想起测故障域

别等故障发生了才想起测故障域
别等故障发生了才想起测故障域

很多团队的故障域设计,就是架构师坐在办公室里画个图,贴在wiki上就算完事了,从来没真的验证过这些隔离到底有没有用。

我们那次故障之后,专门搞了每月一次的混沌演练,不是那种在测试环境里点个按钮的假演练,是真的找云厂商打好招呼,直接掐掉某个电力分区的网络,断了某个批次的交换机链路,看核心服务能不能真的自动切走。

第一次演练就吓出一身冷汗。我们掐了整个可用区的出口网络,盯着控制台等告警,等了十分钟啥动静没有。后来才发现,我们的短信告警网关,就部署在这个可用区里,网络断了,告警根本发不出来。最后还是楼下的保安打电话,说机房的消防灯闪了,我们才知道出问题了。

你看,很多时候你以为的全链路隔离,连运维通道本身的故障域都没考虑到。要是真遇到大故障,你连出问题的通知都收不到,谈什么恢复?

说实话,我之前也觉得故障域设计是架构师用来装逼的概念,直到那次双十一的损失砸到脸上才明白,这玩意儿是要拿真金白银换的。

不过话说回来,也不用把这事儿想的太复杂。你回去就拉上运维和云厂商的对接人,花一下午把核心服务的所有共享依赖列出来,看看哪些东西挂了会连带搞坏所有副本。再挑三个最核心的业务,做一次真刀真枪的故障注入测试,看看你画的故障域边界到底有没有用。

就这么简单。