或多或少我们都会经历线上的故障。在我的职业生涯中,就经历过很多的线上故障。老实说,线上故障是我们技术人员成长中必须要经历的事。从故障中我们可以吸取到很多教训,能让我们学到很多书本上学不到的知识。坑踩多了,我们会变得越来越有经验,也就成为老司机了。
不过,我看到很多公司处理线上故障的方式并不科学,而且存在很多问题,所以,想写文章来分享一些我的经验。这些经验主要来自亚马逊和阿里这两家互联网公司,以及我个人的经验总结。希望这套方法能够对你有帮助。
在故障发生时,最重要的是快速恢复故障。而快速恢复故障的前提是快速定位故障源。因为在很多分布式系统中,一旦发生故障就会出现“多米诺骨牌效应”。也就是说,系统会随着一个故障开始一点一点地波及到其它系统,而且这个过程可能会很快。一旦很多系统都在报警,要想快速定位到故障源就不是一件简单的事了。
在亚马逊内部,每个开发团队至少都会有一位 oncall 的工程师。在 oncall 的时候,工程师要专心处理线上故障,轮换周期为每人一周。一旦发生比较大的故障,比如,S1 全部不可用,或 S2 某功能不可用,而且找不到替代方案,那么这个故障就会被提交到一个工单系统里。几乎所有相关团队 oncall 的工程师都会被叫到线上处理问题。
工作流是,先线上签到,然后自查自己的服务,如果自己的服务没有问题,那么就可以在旁边待命(standby),以备在需要时进行配合。如果问题没有被及时解决,就会自动升级到高层,直到 SVP 级别。
大家都知道,在亚马逊,不是按技能分工,而是按职责分工,也就是一个团队不是按前端、后端、运维等来分工,而是按所负责的 Service 来分工。所以,亚马逊的开发人员都是前端、后端、测试、运维全部都要干的。而亚马逊内部有很多的服务,一旦出现问题,为了避免一个工单在各个团队流转,需要所有团队上线处理,这样是最快的。
如果我们的系统架构是分布式服务化的,那么一个用户的请求可能会经过很多的服务,开发和运维起来是非常麻烦的。此时,跨团队跨部门的开发和运维就变得非常的重要了。就我的经历而言,在故障发生时,亚马逊的处理过程是比较有效和快速的,尤其是能够快速地定位故障源。对于被影响的其他团队也可以做一定的处理,比如做降级处理,这样可以控制故障的范围不被扩散。
故障源团队通常会有以下几种手段来恢复系统。
也就是说,出现故障时,最重要的不是 debug 故障,而是尽可能地减少故障的影响范围,并尽可能快地修复问题。
国内的很多公司,都是由专职的运维团队来处理线上问题的。然而,运维团队通常只能处理一些基础设施方面的问题,或是非功能性的问题。对于一些功能性的问题,运维团队是完全没有能力处理的,只能通过相应的联系人,把相关的开发人员叫到线上来看。而可能这个开发人员看到的是别的系统有问题,又会叫上其它团队的人来。所以,一级一级地传递下去,会浪费很多时间。
为了能够在面临故障时做得有条不紊,我们需要做一些前期的准备工作。这些准备工作做得越细,那么故障处理起来也就越有条理。我们知道,故障来临时,一切都会变得混乱。此时,对于需要处理故障的我们来说,事可以乱,但人不能乱。如果人跟着事一起乱,那就是真正的混乱了。
所以,我们需要做一些故障前的准备工作。在这里,我给出一些我的经验。
这个视图最好是由相应的自动化监控系统生成。有了这个资源图后,我们就可以很容易地找到处理故障的路径了。这就好像一张地图,如果没有地图,我们只能像个无头苍蝇一样乱试了。
比如 Redis,怎样检查其是否存在问题,怎样查看其健康和运行状态?哪些是关键指标,面对常见的故障应该怎么应对,服务不可用的服务方案是什么,服务需要回滚了应该怎么操作,等等。这就好像一个导航仪,能够告诉你怎么做。而没有导航仪,就没有章法,会导致混乱。
制定故障等级,主要是为了确定该故障要牵扯进多大规模的人员来处理。故障级别越高,牵扯进来的人就越多,参与进来的管理层级别也就越高。就像亚马逊内的全员上线 oncall 一样。这就好像是我们社会中常用的“红色警报”、“橙色警报”、“黄色警报”之类的,会触发不同的处理流程。
在亚马逊,发布系统中有一个叫 Weblab 的系统,就是用来做灰度发布的。另外,亚马逊全球会有多个站点。一般来说,会先发中国区。如果中国区没什么问题了,就发日本区,然后发欧洲区,最后是美国区。而如果没有很多站点的话,那么你就需要一个流量分配系统来做这个事了。
好了。今天就分享这么多。只要能做好上面的几点,你处理起故障来就一定会比较游刃有余了。
在这篇文章的末尾,我想发个邀请给你。请你来聊聊,你所经历过的线上故障,以及有哪些比较好的故障处理方法。