2023年的互联网世界,“草台班子”、“降本增笑”、“开猿节流”成为大家互相调侃的关键词。苦笑过后,问题还在,事故终要复盘,未来仍需规划。从架构角度看,我们应该怎么去认清高可用的本质,并真正在业务场景中做好高可用,这是本文想跟大家探讨的问题。
2023年过去了,但是相信没多少技术人会特别怀念它。这是不平静的一年:首先是大大小小的公司各种花式裁员,35岁危机的焦虑在行业蔓延;其次就是各个大公司萝卜蹲式的各种 P0/P1 故障,频繁占据了热搜榜单。虽然事后各个公司公布的故障原因五花八门,例如有的故障是因为某地域 IDC冷冻系统故障,有的故障是因为升级工具 bug 导致服务器被误下线,有的故障是因为 K8s 版本升级导致容器全部宕机……等等。但是这样的解释很难让人信服为什么2023年会成为多事之秋的一年,毕竟机房故障、各种升级操作等以前也都存在,并不是2023年独有的。
那到底是什么原因导致各个大公司频繁的线上故障呢?突然之间,“降本增笑”成了大家的共识:因为公司裁掉了经验丰富的35岁以上的一二线老员工,留下来的技术人员有的是年轻的,有的是便宜的,有的是新招的。虽然可能降了成本,但是很多系统踩坑经验和隐含陷阱都随着老员工的离去而丢失,系统容易出问题也就不奇怪了,而一旦出问题又没有经验丰富的老员工能够快速处理,问题影响变得更大,持续时间变得更长,之前各种技术大会上 PPT 写的天花乱坠的异地多活、高可用等高大上的方案,也都形同虚设,成了全网吃瓜群众的笑料。这个解释确实有一定道理,但是是不是不降本就不会增笑呢?其实远没有那么简单,今天我们就来聊聊构建持续高可用系统背后的困境和挑战。
01高可用的达摩克利斯之剑
首先,思考一个终极的类哲学问题:我们能否构建出永不出问题的系统,或者退一步讲,能否构建出不出大问题的系统?很遗憾,答案是“不能”,因为有两条定律成了高可用系统上面悬着的达摩克利斯之剑。第一条定律是“熵增定律”: 在一个孤立的系统里,如果没有外力做功,其总混乱度会不断地增大,最后达到一个无序的状态。
“熵增定律”本来是描述物理学方面的系统的,但是类社会的各种系统也是完全符合“熵增定律”的,无论是我们所处的公司,还是我们开发的各种软件系统,都会遵循“熵增定律”。对于软件系统来说,“熵增”是无处不在的。例如:为了完成某个领导年度 KPI,原本需要6个月的项目,被压缩到2个月,代码加班加点才能写完,怎么方便怎么来,埋下大量的隐患和暗坑;产品经理为了绩效堆需求数量,做了大量无用又别扭的需求,代码经手了一茬又一茬的人,被改得复杂又看不懂,新需求都是另起一个if重新写,系统慢慢成了“代码屎山”;为了在市场竞争中先对手一步,技术团队被当成生产队的驴一样驱赶做各种新需求,技术债越来越多,但只要不到崩溃那一天,是不可能有机会停下来清理技术债的;好不容易花大力气做完了重构,后面新来的人不熟悉,又是按照自己的理解来到处改,团队又没有 code review 机制(代码都写不完,谁还有时间和精力去 code review ),重构的模型和约定慢慢又被腐化了;技术不断在发展,各种新技术层出不穷。
技术团队不管是为了自己的绩效也好,是为了业务的发展也好,最终都会大概率选择不断尝试和引入新技术。虽然确实能享受新技术的一些好处,但也带来了复杂度和风险的增加。这些问题有破解方法吗?看起来都可以破解,“只要……” 就行了,但实际落地会发现,一个都破解不了,因为有人的地方就有江湖,而技术团队在这些场景中,基本都是最弱势、最没有话语权的。第二条定律是“墨菲定律”:任何可能出错的事情最终都会出错。
好吧,假设我们的老板真的懂技术愿意给技术团队偿还技术债,假设我们的 leader 真的时刻关注系统质量,假设我们的产品也都像微信张小龙一样尽量克制,是不是就意味着我们的系统就不会出大问题了呢?很不幸的是也做不到,墨菲定律告诉我们只要你的系统还在运行,就总有可能出错的。
例如:机房空调可能会损坏,服务器可能起火,网络可能被挖掘机挖断,网线可能被老鼠啃破,海底光缆可能被船拉断;你用的 MySQL 一定会有 bug,K8s 也一定会有 bug,Nginx 也一定会有 bug……等等;你的系统代码也一定有 bug,只是你现在不知道 bug 在那里而已。有的人可能会说,我们做了异地多活架构啊,出故障后切换就可以了。但实际上异地多活本身可能就有问题,异地多活相关的辅助系统在真正需要切换的时候也可能用不上。
基于上述分析,我们可以看到,构建永不出问题的系统是不可能的,如果你的老板看到出了问题就说技术团队不行,那么我建议你可以尝试给他科普一下“熵增定律”和“墨菲定律”:)当然,我们也不能拿“熵增定律”和“墨菲定律”来作为躺平的借口。虽然无法构建永不出问题的系统,但也不能让系统天天出问题,所以我们还是需要考虑如何去构建持续高可用的系统。
02构建持续高可用系统的困境
但是在实际落地高可用建设的时候,会遇到第二个挑战:神医悖论。“神医悖论”是我从扁鹊回答魏文侯的问题里面概括的一个名词。原文大意是魏文侯问扁鹊三兄弟中谁的医术最高明。扁鹊回答说:“长兄最善,中兄次之,扁鹊最为下。”扁鹊医术精湛,神医名声远播,为什么扁鹊却认为大哥二哥比他强呢?扁鹊解释说:大哥治病于病发之前,一般人不知道他事先除去了病因,故而他的名气无法传出去;二哥治病于病情初发之时,一般人以为他只能治轻微小病,故而他的名气只及本乡里;而扁鹊治病于病情严重之时,所以他们认为扁鹊的医术最高明。我们在建设高可用系统的时候,一样会遇到“神医悖论”。不管公司是有专门的 SRE 团队,还是各个团队的直接负责系统高可用;也不管公司是为了可用性做了很多基础系统,还是各个团队靠人力来保障可用性,都会面临这个问题:你怎么证明你的可用性做得好?你的可用性投入是有很大价值的?
假设1年没出问题,能说明是你的可用性工作做得好吗?很难,因为大概率可能是你运气好。所以也许有时候去庙里烧点香,也能达到这个效果。某互联网大厂以前准备双十一的时候,很多团队都会事先去灵隐寺拜一拜的,据说确实拜了和不拜有差别。假设今年出了一个 P0 问题,就能说明你可用性工作做的不好吗?也不一定,因为也可能是你运气不好。即便都是 P0 问题,如果没有你做的这些可用性工作,时间可能从1小时变成6小时,损失可能从1000万变成8000万,而你做的可用性工作,投入才100万。你兢兢业业地像扁鹊的大哥一样,做了很多事情把各种问题都消灭在萌芽状态,全年下来没有发生任何 P0/P1/P2 故障。年底汇报的时候回过头来一看,全是一些看起来鸡毛蒜皮的事情,你怎么汇报才能拿到绩效?相反,隔壁团队虽然上半年出了一次 P0 故障,但是换了一个 leader 后,新 leader 大刀阔斧重构架构,搞多活建设,年底汇报 PPT 都写了50页,绩效不是 S 就是 A。你难道跟老板说“我是扁鹊大哥,他只是扁鹊而已”?
从技术的角度来说,构建持续高可用的系统实际上就是要和扁鹊的大哥一样,要花费很大的时间和精力来做各种琐碎的事情,将问题消灭在萌芽状态。虽然不能彻底消灭所有问题,但是可以大幅度减少发生大问题的概率。例如:单元测试、code review,数据库设计规范、监控系统、应急系统、架构评审、方案评审、系统重构、全链路测试、混沌测试、故障定期演练、灰度发布……等,这些事情散落在各个团队,项目的各个阶段,但是都和高可用有一定关系,对持续高可用有一定的作用。但是从人的角度来说,要想通过高可用建设拿到好的绩效,却需要和扁鹊一样。只有等到系统已经被证明不行了,系统故障影响太大了,老板或者领导才会突然发现可用性的价值,才会给予技术团队时间、人力、资金来做高可用建设。例如:微服务演进、弹性架构、同城双活、异地多活、多云建设、混合云演进……等,一看这些技术名词就能看出来高大上,规划这样的项目,技术团队干起来都特别有劲,年底汇报写 PPT 都能写出花来。
从老板的角度来讲,一样也面临神医悖论带来的挑战。假设老板心甘情愿每年投入1000万给某个团队来做高可用,最后年底一看1000万下去,就做了一堆琐碎的事情,心里肯定也会有疑惑:你们这帮小子,拿了我1000万,弄了一个几十人的团队,一年到头就干这点事?如果老板愿意投钱的时候都会有这种困境,那么当老板开始“降本增效,开猿节流”的时候,更加会毫不意外地优先裁掉做可用性建设的团队和人员,而往往在团队里面负责这部分工作的员工,都是经验丰富但成本也高的老员工。于是乎,“降本增笑”几乎成了不可避免的结局。
03破局之道?
综合上述的分析来看:结果的不确定性,价值难以准确衡量,工作不容易被看见等因素,让实践中的高可用工作都变成了运动式高可用攻坚项目。简单来说就是陷入了一个无解循环:前人积累太多技术债,系统磕磕碰碰逐渐越来越不稳定,但是没有人愿意花太多时间去整体解决,只希望保证击鼓传花的雷不要在自己手里爆炸即可。等到哪一天某个倒霉蛋运气不好,系统终于发生了“史诗级”的故障,成功让公司上了热搜;此时老板或者大领导们终于顿悟:如果系统再来一次类似的事故,业务或者自己可能就要吃不了兜着走了。
于是公司或者大领导开始了运动式的高可用攻坚项目:先找一个原来的倒霉蛋背锅,让他走人或者降级;然后找一个新的幸运儿来负责高可用的“彻底优化”。幸运儿来了之后肯定不会走扁鹊大哥的路线,而是直接整高大上的项目:重构、双活、多活、多云、混合云等。基本上这样的项目建设可以做1年,彻底完善可能需要2年。做完后系统整体的高可用能力确实能上一个新的台阶,毕竟那么多问题都明摆着,光解决这些问题就能够很大提升系统质量,更何况还做很多高可用的架构、基础设施等,肯定能够大幅提升系统的高可用能力。于是新的幸运儿大概率会升职加薪,走向新的职业巅峰,老板或者大领导们也终于放心了。
但是系统正是从这时候开始又慢慢地进入了新的一轮循环:继续拼命赶项目忽视质量;继续堆各种杂乱的需求;原来做高可用相关的人员逐渐缩减,调岗到其它业务开发团队……就这样又慢慢地逐渐退化,直到新一轮的运动式高可用攻坚项目来临。有什么有效的破局之道打破这个循环吗?坦白的说:几乎没有。绝大部分人能做的就是期望自己不要成为这个循环中的倒霉蛋,或者自己能够成为这个循环中的幸运儿。
如果说一定要打破这个循环,其实关键不在技术团队身上,而是取决于老板和大领导们。当然,并不是要老板和大领导们自己买一本《SRE 谷歌运维揭秘》的书籍自己去学习如何做高可用建设,关键在于转变对持续构建高可用系统的认知,然后鼓励技术团队持续在高可用方面进行一定的投入。
首先,意识到系统和人类似,高可用的系统需要持续建设。健康的系统和健康的身体都是要持续投入的,而不是靠一段时间内突击运动和打兴奋剂。在日常的工作中,给技术团队留出一定的时间和精力来做一些高可用方面相关的工作,即便这些工作看起来在当时都没有明显的作用。其次,不要那么功利化。在高可用方面保持一定的人员和投入,即便看起来这些都是“成本压力”。就像人锻炼一样,很难说今天跑了 5KM,身体就一定变好了,甚至有可能今天跑了 5KM,过两天还会感冒发烧。但长期来看,坚持锻炼的人身体大概率会比不锻炼的人要好很多。因此,公司和组织可以安排一些人员来专门负责高可用方面的一些工作,保证高可用相关的一些系统、工具、规范有人去推动落地。就算这些人没事找事,那他们也是在寻找系统中的一些隐患和不足,或者尝试对系统进行优化和加固。第三,坚持定期给系统体检和保养。就像人需要定期体检,车子需要定期保养一样,系统也需要定期的检查和保养。千万别不出事就万事大吉,出了事就莫名惊诧!可以每年给系统进行一次小的复盘和盘点,每两年给系统进行一次全面的检查和优化,大概率就可以避免一些灾难级的故障发生。即便运气不好发生了严重事故,也可以大大减少故障的影响时间。要知道1个2小时的 P0 故障和一个12小时的 P0 故障,虽然等级都是一样,但是影响和破坏力是天差地别。
总而言之,构建持续高可用系统的破局之道,其实在于公司和组织的技术文化上,而非技术手段。
作者简介
前阿里 P9 级资深技术专家,16年软件设计开发经验,曾就职于华为、UC、阿里巴巴、蚂蚁金服,承担架构设计、架构重构、技术团队管理、技术培训等职责;专注于开源技术、系统分析、架构设计,对互联网技术的特点和发展趋势有较深入的研究和理解,对于高性能、高可用、业务架构、系统解耦等有丰富的经验,著有《编程的逻辑:如何用面向对象方法实现复杂业务需求》、《从零开始学架构》,极客时间专栏《从0开始学架构》、《大厂晋升指南》作者,极客大学《架构实战营》讲师,博文视点20周年20人作者。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。