今日内容
今天开始,我们进入到【系统铁三角】的最后一个版块,也就是【稳定性】板块。
这个板块的内容重要且多,我会分成多篇文章来给你讲。你不用着急,我会用容易理解的方式给你铺陈。
全部看完以后,我相信你对如何让系统跑得“稳”,会有完全不同的认识以及信心。
今天我们先来做一个概览,来看看稳定性到底涉及到哪些方面的内容,为什么我们会需要花好几篇文章来讲稳定性。
01稳定性的重要性
在讲具体稳定性方面的内容前,我们先来聊一个话题,那就是,稳定性到底重不重要?如果稳定性都不重要的话,我们就没有必要做那么多展开了
我们从一个角度切入来看,那就是:如果服务不可用,会有怎样的影响?
我们看下图:
从公司收益的角度来看,会有两方面损失:
【直接损失】比如你的产品需要充值才可以使用,然后你的充值服务挂了,用户想充值都充值不了,这就是最真金白银的损失,是公司收入的损失。
【订单损失】订单往往涉及到佣金。比如一个电商平台,每一笔成交的订单,平台都可以抽取佣金。如果交易服务持续不可用,订单就生成不了,佣金就损失了。佣金也是公司真金白银的直接收入。从用户体验的角度来看:
【热搜(社会舆论)】一个国民级应用如果不可用了十几二十分钟,铁定上热搜,造成不好的影响。
【信任感】用户使用一个产品,也许是他很重要的时候。比如外卖平台,用户中午要吃饭,然后发现外卖平台怎么都登录不了。但饭总要吃啊,于是就去别的平台点。久而久之,用户对你的信任感就丢失了,也就不再来了。
【直接影响】比如有些用户对某些产品是重度依赖,依赖到不可或缺。例如支付类的产品,现在在医院看病都可以使用手机支付,然后某天突然支付不了检测费药费了,你说严不严重?
这三方面最后造成的就是对产品口碑的影响,继而开始慢慢地损失用户。而损失用户这种慢性地负面影响最终也会对公司的收入造成影响。
大家可以看到,最后所有的影响都是指向收入损失,而收入最终影响着企业的存活和发展。
02故障的种类
在聊完了稳定性为什么重要以后。我们来思考一个问题,服务跑得好好的,为什么会挂呢?服务之所以出问题,那一定是发生了故障。所以,我们来看看故障的种类。
我们看下面这张图:
【变更类】:变更不只是【代码变更】,还包括【配置变更】和【数据变更】。这些变更,无论是参数改错了,还是DB数据订正错了,都可能导致严重的故障。
【容量类】:比如一款秒杀商品上架,上游流量扩大了100倍,服务直接就崩了。再比如做压力测试,直接一下子压力打得太大,直接把线上服务器打崩。
【依赖类】:在现在分布式架构盛行的背景下,一个微服务的直接和间接依赖是非常多的。下游的某个服务、缓存、DB如果挂了,自己就会被“牵连”,无法提供正常服务。
【固件类】:机器的硬件故障,例如硬盘坏了,电容烧了等等。还有一种叫做区域性灾害,比如某个地方施工,一铲子把地下的光缆给铲断了。
【安全类】:例如黑客的攻击。比如做DDOS攻击、水平权限攻击、伪造大量造成缓存穿透的请求等等。
这些故障类别里有一个点值得关注,那就是:只有变更类的故障是由我们主动的行为造成的,而其他的故障多
少属于飞来横祸。但他们依然会造成严重的影响。
所以,即使是无妄之灾,我们也要想办法优化和避免。这是稳定性非常非常难的一个原因。
03系统可用性指标
我们讲了稳定性既重要又困难,那就需要有一个指标去衡量稳定性做的如何,并且以此为尺,衡量各种改进的效果。
稳定性的衡量可以看如下这张图:
上图公式中,分母是MTTF+MTTR,分子是MTTR。什么意思呢?我来解释一下
【MTTF】是指平均正常时间,也就是MeanTimeToFailure。比如一个系统,平均每跑一个小时就会挂一次,那MTTF就是60分钟。
【MTTR】是平均修复时间,比如说每次修复故障需要10分钟,那MTTR就是10分钟。
针对上面的公式,我们举个例子:平均每个月出一次故障,每次故障修复需要10分钟,那么系统可用性就是99.97%,也就是我们俗称的3个9。
下面我们来看一个表格。我们一般用系统符合N个9来衡量和要求系统的稳定性。
这个图很好理解,例如我们要求系统可用性达到4个9,那全年系统不可用时间最多就是52分钟。其他同理。
一般来说,大厂对外的服务基本上都要求达到4个9。
所以,结合我们说的。首先,故障种类多且大部分都是无妄之灾,然后对服务稳定性又有非常高的要求。你就可以得出:稳定性真的是一件难上加难上加难的事情!
04如何提高可用性
我们聊了那么多重要性和困难后,还是要给方法。那如何提升可用性呢?
我们从系统可用性的公式出发来看,想要提高系统可用性,就是要降低MTTR,也就是缩短故障修复的时间。
我们可以从三个方面来降低MTTR,他们分别是:【减少故障数量】【提升发现速度】【提升恢复速度】。
下面我们先一览三个方向相关的内容,这些内容在后面的几篇文章中,我会再展开来说。
01减少故障数量
我们先讲如何减少故障数量,先看下图:
这个图是我们日常的工作过程。
需求过来,然后研发,接着测试,上线,上线后系统就持续地运行。周而复始,直到这个系统下线。
为什么我放这个图?因为三个提升稳定性的方向其实都是融入在我们平时的日常工作中。
在研发阶段,我们可以关注【隔离】【幂等】【限流】【兼容性】等。
【隔离】不同的功能不相互影响。
【幂等】请求重复,但结果不受到影响。
【限流】在流量大的时候,自动拦截保护服务。
【兼容性】新旧代码共存时,系统能够正常服务。
在测试阶段,我们可以关注【功能测试】【回归测试】【兼容性测试】【流量diff】等。
【功能测试】测试新开发的功能是不是符合预期。
【回归测试】测试新代码没有对已有逻辑造成影响。
【兼容性测试】验证新旧功能共存时,系统是否正常运行。
【流量diff】把线上流量录制下来,在待上线代码上做回放,比对结果。
在上线阶段,我们要考虑【发布顺序】【压测容量】【灰度策略】等
【发布顺序】比如服务A必须在服务B之前发布,先发布服务B就会报错。
【压测容量】新功能上线,是否能够抗住业务的预期流量,我们需要先做压测验证。
【灰度策略】让新变化能够逐步地生效。比如可以让一部分内部用户先试用,这样可以降低问题的影响面。
02提升发现速度
我们接下来看如何提升发现速度。这些内容依然是在我们的日常工作中。
在研发环节,我们可以关注【日志】和【打点】等
【日志】在写代码的时候加上关键的日志。比如最基础的对异常捕获后的日志、对下游服务调用的日志、出入参日志、业务关键流程的日志等等。
【打点】系统中主动上报数据到监控系统。比如电商浏览页面,你可以把用户查询的商品金额上报,然后配置对金额的监控。如果发现大量金额为0的情况,就说明可能存在系统级别异常。
在运行环节,我们可以关注【监控报警】【日常巡检】【数据核对】等
【监控报警】配置全面的监控,搭配上恰到好处的报警规则。
【日常巡检】周期性主动探测各种链路是否正常。
【数据核对】对上下游系统的单据进行核对,发现单系统内的潜在bug。
03提升恢复速度
最后我们来说第三块,提升发现故障后的恢复速度。
在研发阶段,我们可以关注【工具建设】【容灾切换】【降级开关】【流控设置】等。
【工具建设】针对系统中可能存在的一些问题,建设检测或者修复的工具。例如修复缓存数据库不一致的工具。
【容灾切换】在服务发生线上问题时,快速的切换流量和设施。比如设计时考虑了备份DB和缓存,在发生问题时可以快速切换。
【降级开关】在发生异常情况时,可以绕开或者忽略某些错误情况。例如展示用户信息需要展示vip等级。如果vip等级服务挂了,可以不展示vip等级,其他信息不受影响。
【流控设置】通过对流量设置上限,保护自身服务不被流量打垮。
在运行阶段,我们可以通过【限流】【禁用】【扩容】【回滚】等快速恢复。其中部分能力刚才我们已经提到。
【限流】配合上面提到的限流能力,能够在运行时对流量进行调整。
【禁用】直接让一台机器停止提供服务。这样可以在单机问题时,快速移除有问题的机器。
扩容】流量上涨之后,快速扩充机器抗住流量。
【回滚】撤销之前做过的线上变更。我们提到过变更有多个种类,每一种都要考虑回滚方案,保证出问题时快速消除影响。
04落地细节总览
结合上面说的内容,我们再整体一览稳定性在各个环节涉及的内容。这些内容我们会在后面的文章中展开。
会从系统设计、变更规范、故障监测、故障处理、故障复盘这几块分多篇文章来展开。
其中我们可以看到,最后【故障复盘】会用来完善之前的多个环节,这样一来,就形成了一个【增强回路】,让我们的稳定性越来越好。
05稳定性的复杂性
讲了前面那么多,我相信你已经感觉到“稳定性”这件事情很复杂。重要、风险高、环节多、要做的事情也多。
你有这样的感觉非常正常,因为稳定性确实很复杂。
在大厂,往往有很多同学专门负责稳定性。也有稳定性相关的团队,这样团队的TL级别也往往不低,直接挂在CTO的下面。
下面我就再用一张图,帮你梳理下稳定性的复杂性。
上图中,我分别从五个角度做了描述,大家看图就能全方位感知到复杂性。并且这张图里也蕴藏着解决稳定性问题的思路。
所以,如果你想要做好稳定性,你要有充足的思想准备。稳定性是对技术人综合能力的考验。除了技术方面,还有协作能力、耐心等等。
当然,最重要的是,跟着我们的系列文章往下走。当你看完所有稳定性相关的内容后,我相信你一定会很有信心做好这件事情。
今日小结
今天我们开始【系统铁三角】的稳定性内容。我们讲了“稳定性为什么重要”、“故障有哪些种类”、“如何衡量系统的稳定性”以及“如何提升稳定性”。
总的来说,稳定性是一件非常复杂的事情,但非常重要。今天我们的内容只是一个开头,后面我们会有多篇文章来展开这些细节。力求帮助你可以在实际工作中,让系统变得更稳。
强烈推荐你持续关注,这是来自大厂实实在在的干货。