活动背景微盟是中国移动互联网营销的领导者,也是中国最大的微信公众智能服务平台。基于微信,为企业提供开发、运营、培训、推广一体化解决方案,帮助企业实现线上线下沟通。定制化客户关系管理、移动电商、轻应用等2月23日19:00,微盟发生大规模系统故障。据官方消息,这是由于运维部一名核心员工在生产环境中进行“删库”操作所致。截至发稿,系统仍处于修复阶段,预计将于2月28日24:00完成全部修复。在此期间,微盟启动了应急响应机制,并在腾讯的大力支持下Cloud,我们一起研究制定了生产环境和数据恢复方案。历史上类似事件说到“删库跑路”,历史可以追溯到《西游记》。还记得孙悟空大闹阴间,逼迫地狱的“地狱数据库”(Hell-DBMS),其实就是生死簿,被改得面目全非的故事。相传孙猴拿起一把大毛笔,在自己的名字和猴孙孙辈的名字上划上一笔,以此来避免生老病死的轮回。很显然,这个地狱数据库显然根本就没有备份过,从头到尾只有一份,而且一旦删除,就再也回不去了。当然,这只是我的一个玩笑,但它显示了备份的重要性以及在系统故障时恢复的能力。此类事件在IT历史上并不少见。2015年5月28日11点左右,携程官网和APP同时崩溃。一时间,网上流传着携程数据库被物理删除的说法,直到深夜23:29。才渐渐恢复过来。次日,携程发布官方解释,称是运维人员操作失误,导致生产服务器上的执行代码被删除,最终的详细报告并未正式发布。另一个著名事件是,2017年2月,Gitlab.com数据库也被误删。当时由于DDoS攻击,暂存数据库(db2.staging)落后生产数据库(db1.cluster)4GB的数据,而暂存数据库由于PostgreSQL的问题处于挂起状态。在试图修复这个问题的过程中,导致了删错库的错误操作,最终导致很多项目代码不同程度的丢失。之后,顺丰、广西移动等类似事件相继发生。微盟对危机的应对值得借鉴微盟的删库事件给不少行业用户造成了不小的影响,但在危机面前,微盟的社会责任感值得学习。面对突如其来的故障,微盟并没有试图掩盖真相,而是第一时间在官网发表声明,解释了事件的原因,并明确告知了后期恢复计划的时间点。得到澄清。要知道,微盟也是此次事件的最大受害者。在这背后,我们的运维人员会有多少个不眠之夜,可想而知。在此期间,腾讯云给予了大力支持和帮助,派出众多一流的技术专家,不计成本地支持微盟和微盟的客户。多一些诚意,少一些套路,共同处理问题,才是面对这种危机的最好方式。如果你想掩盖,掩盖不了就撒谎,再像张宇唱的那样“用一个谎言来完成另一个谎言”,势必会让自己陷入更深的危机。危机之下,我们要的是公开信息,减少舆论猜测,抵制黑公关,得到大家的理解和支持。为什么恢复时间这么长?接下来的问题是,既然微盟已经全力修复,腾讯云也提供了很大的技术帮助,为什么要这么久才能完全恢复?圈外的同学可能觉得这应该不会很复杂。是不是感觉重装系统了?不应该备份所有数据库吗?事实上,事情远比你想象的复杂。很多时候,人们往往会有认知偏差。对于一个没有亲自参与过的领域,我们会不自觉地对难度做出错误的判断。这种所谓的自信是很难克服的。这方面的例子很多。比如看球赛的时候,有人想把电视砸了。他们总觉得有的选手好挫败,但是如果轮到你上场,你能比他好吗?另一个例子是兰州拉面。似乎并不难。面条划几下就拉出来了,可是如果是你,你能把那碗面条拉出来吗?其实熟悉现代软件架构和运维的同学肯定都知道,现在的软件架构和部署是极其复杂的,尤其是在微服务大行其道的今天,每个微服务本身都有一个集群,微服务和微服务之间还是有联系的.存在各种依赖关系,每个微服务都可能与数据库打交道。大家了解这些服务之间的依赖关系和配置就够了。更何况,这次微盟事件并不是局部的更新发布,而是对几乎整体架构的全局审视。从这个意义上说,这不亚于从头开始构建整个系统的难度,更何况是在如此巨大的商业压力和舆论压力下。让我们再看看数据库。根据目前官方的信息,应该是在生产环境的本地库中不可逆删除了数据库,不然也不会花这么长时间。假设本地生产库没有了,唯一的办法就是使用异地容灾的全备库来恢复,但是这样也会带来一系列的问题,比如异地库容量大,需要大量网络传输时间的问题,例如增量备份的完整性不足。另外,近期数据方案变更导致的备份数据兼容性问题也会出现。这些都需要研发人员和运维人员的共同推进,需要更多的时间。对运维演进的冷思考通过这次事件,站在运维的大局观,能给我们带来哪些启示?这里我提出4个问题作为我们讨论的主线。问题1:普通人可以在多大程度上扰乱系统?先说说我的观点:在信息时代,一个普通人完全可以摧毁一个系统。是的,你听到的是对的。这种事情在信息时代之前是很难想象的。在人类历史上,一个人决定一个民族、一个朝代的走向并非闻所未闻,但那一定是那些位高权重的人物。你有没有听说过,当两个普通人聊天的时候,让我们一起改写人类文明和外星文明。听上去很荒唐,但刘慈欣的小说《三体》里却发生了这样的事情。地球人叶文杰和三体人1379是各自世界里的小人物。叶文洁对人很失望,1379对生活很失望,双方建立联系后,在接下来的几百年里改变了人类世界和三体世界的命运。虽然这只是小说中描绘的场景,但所有的逻辑都是自洽的,就连霍金在接受采访时也表达了同样的观点。回到运维和DevOps,大家有没有发现很多互联网产品运维人员的权限其实非常大,有时候大到可以直接毁掉一个系统,这种现象出现在一些B轮或者C轮公司尤其常见。先不说运维人员会不会恶意破坏自己的系统,但是忙着出错的概率还是不小的。Gitlab.com数据库被删除,其实是运维人员操作失误造成的。由于终端窗口的反复切换过多,导致本应在staging上进行的删除数据库操作,在生产环境中竟然发生了,最终酿成大祸。因此,这个问题给我们带来的启示是,要充分关注个体在系统中可能发挥的作用,就必须严格监督个体的行为,避免个体造成系统失灵。这也是为什么大企业会建立比较完善的分级分级发布流程,层层监管审批,避免个别单点故障无限放大。当然,这些监管和审批必须纳入技术驱动的DevOps流水线中才能完成,而不是依赖传统的领导签名。问题二:“人肉运维”的生存空间有多大?首先解释一下“人肉运维”。我认为在生产环境中直接敲命令完成的各种运维操作都属于人肉运维的范畴。记得左耳鼠标说过“一个公司运维能力的强弱,与你在生产环境中输入的命令数量成正比”。运维能力越弱,在生产环境直接执行各种命令的频率就越高。越高,运维能力越强,人直接与生产环境打交道的机会就越少。生产环境的所有变更,无论是系统参数、安全策略、网络配置、应用参数、环境参数、文件更新,还是数据库更新,都应该通过DevOps流水线走正式发布流程,所有操作都必须执行通过脚本。或者自动化代码来做,应该没有人会有直接在生产环境进行命名操作的场景。这样做的好处有:发布过程的详细过程可以记录和追溯;发布过程可以重复进行,避免操作步骤遗漏或出错,保证集群中节点状态的一致性,这对于集群扩容场景非常重要;避免生产环境中人为产生的随机错误;所以,这个问题的结论很明显,我们应该尽可能避免任何形式的人运维,我们的行为准则是??“人管理代码,代码管理机器”,而不是“人直接管理机器”。问题三:运维积累了很多实践,为什么还在苦苦挣扎?随着软件架构复杂度的不断提高,运维的理念和技术手段也在不断演进。从早期的运维,到现在的DevOps,再到日趋完善的AIOps,我们积累了大量的经验和最佳实践,但是为什么看起来我们的运维人还是觉得吃力。我认为这有两个原因。一是现在软件架构的发展速度在一定程度上超过了运维本身的发展。回过头来看,运维的技术体系一直在完善。各种CI/CD工具链、容器技术、自动化部署工具、系统监控方案日趋成熟。我们的运维能力确实在不断提升。但与此同时,运维的对象也变得越来越复杂。无论是依赖关系还是集群规模,它们都比以往任何时候都更加复杂。可以说,“涨潮”是现代运维面临的主要矛盾。.另一个原因是很多运维的最佳实践在实际工作中被“教条化”了,并没有达到这些实践设计的初衷。比如,为了防止人为错误,在做一些关键操作的时候,我们往往会有Peer机制(两个人配对互相检查),Checklist机制(自己检查),但是在实际执行过程中,它往往是形式主义占了上风,这个不用我解释你也能理解,所以这些机制并没有发挥应有的作用。因此,我的建议是将此类方法完全嵌入到管道的执行步骤中,而不是人为地实现它们。我常说“凡是人做的事都不靠谱,要靠技术手段靠谱”。另外,还有一个做法我觉得不太好。在实际工作中为了引起运维工程师的注意,我们会将系统设计成“危机敏感”,即在没有问题的情况下输出大量告警信息,或者很多常见的操作需要您反复确认是否执行。比如你发起某条命令执行某项操作,系统会先报警,然后要求你再次输入“Y”来决定是否继续执行。看起来这是一种风险更低、更安全的设计,但实际上这会造成一些混乱。想必大家都听过“狼来了”的故事。当你每次都觉得这些信息无关紧要时,你会下意识地忽略这些信息,那么当狼真的来的时候,你就惨了。这个问题在之前的波音飞机设计中也遇到过,所以我的建议是只在最需要的操作上开启这种双重确认机制。问题四:运维部是成本中心吗?在很多人眼里,运维部门被归类为成本中心,简单来说就是花钱的部门。运维是成本中心的宿命论其实对运维的发展是非常不利的。如果运维部门长期处于机械发布执行和生产环境救火的状态,就会陷入无休止的恶性循环。很多时候,我们总是解决看得见的问题,看不见的问题往往会聚集在看不见的地方。这样的问题一旦出现,都是大问题。因此,我们需要改变运维是成本中心的思维方式,让运维同学更积极地思考,解决系统性问题。我们一直说待办事项分为两种,一种是重要的,一种是紧急的,即运维同学经常面临的各种救火任务(生产环境Bug修复、Hotfix发布等),另一种是是一个非常重要但不紧急的任务,也就是我常说的未雨绸缪任务(自动化运维、监控数据分析统计、模型获取与优化等)。理想情况下,应将更多的时间花在未雨绸缪上,而花更少的时间在救火上。未雨绸缪任务做好了,救火的概率就会下降。但现实恰恰相反。运维同学每天忙于各种发布和线上救火,无心偿还各个时期欠下的技术债。这种模式难逃成本中心的宿命。关于未雨绸缪任务,我还有两点想说。首先,运维部门需要定期进行一些故障演练,结合混沌工程(ChaosEngineering)的思想,保证系统的健壮性和可维护性,从而应对各种突发的“黑天鹅”事件。这里要强调的是,“纸上谈兵终究会浮浅,但一定要在实践中做到”。只有在实际故障演练过程中,我们才能积累了很多宝贵的实践经验,光靠思考是不够的;其次,对于日常运维中遇到的各种看得见的问题,不能只着眼于表面的解决,要有“追根究底”的精神ofit”。在这里我强烈推荐书上的方法?:问N个为什么。举个书上的例子,“工厂车间发现一大片油渍。通常的处理方法是先把地板上的油污清理干净,最多看看是机器哪个部位漏油,更换有问题的部位。但按照丰田的思路,会引导员工继续追问:为什么地上会有油?因为机器漏油。机器为什么会漏油?因为某个零件老化磨损严重,造成漏油。为什么零件磨损了?因为质量不好。为什么使用质量差的零件?因为采购成本低。为什么要控制采购成本?因为节省短期成本是采购部门的绩效考核标准。”连问N个原因,才找到漏油的根本原因。因此,此次溢油事件的根本解决之道,其实就是改变采购部门的绩效考核标准,防止类似问题再次发生。日常运维工作也是如此。只有这样,我们才能发现和定位那些未雨绸缪的任务。好了,我的分享就到这里了。难的路越来越容易,容易的路越来越难,祝你好运!作者简介:茹炳生,业内知名软件质量与研发工程效率专家,中国商业联合会互联网应用技术委员会智库专家,畅销书作者书《测试工程师全栈技术进阶与实践》。现任DellEMC中国研发组高级架构师,曾任eBay中国研发中心测试基础架构技术总监、惠普软件中国研发中心高级架构师和性能测试专家、阿尔卡特朗讯高级技术总监、以及思科中国研发中心高级工程师等,拥有超过16年的软件开发和技术管理经验。
