注册

我是如何保障亿级用户系统五年0故障

我负责了我们公司几个非常大的平台系统,日均访问量超过了千万级别,用户过亿。其中某个推送系统每天的消息推送量是过亿级别的。尽管流量和用户都巨大,高峰期的请求也非常高,但是这五年来我们没有出现过任何恶性的线上影响用户的定级故障,那我们是怎么样做到的呢?里面有没有一些值得借鉴的方法可以供大家参考呢?


首先并不是说我们这个系统天生就是稳定的,任何人来维护都不会引发故障,而实际上我们在这五年中也迭代了大量的需求,期间也发生过或大或小的一些变更事故、代码事故,但是都被我们良好的机制应急保障的非常成功,所以没有继续上升成影响多数用户的恶性故障,那么我今天就来跟大家分享一下我是怎么做到的。



对于故障的认识


首先是对于故障稳定性的认知上面。我经历过很多故障,特别是刚开始毕业的时候,由于自己的经验不够成熟,对于系统的故障的认知不够全面,所以导致了一系列影响线上客户的问题,而有一些还被升级成了定级故障。


所以对于大流量高并发的系统来说,最首要就是要建立对系统故障的认知。一个页面一个人访问,100个人访问和1万个人访问,它的影响面是不同的。研发同学对于自己所构建的系统能够影响多少用户应该有一个清晰的评估。比如我现在维护的系统每天的访问量有几千万,所以它的稳定性是至关重要的,稍有不慎可能会引起大面积的用户不可用。


作为研发同学,一定要认识到故障对于用户的体感来说是非常恶劣的,我们这个职责本身就要求我们要敬畏线上进敬畏客户,特别是对于我们这种实时系统,一旦发生了问题,用户可用性就会被打断,有时候造成的影响甚至是无法挽回的。


因此,对故障的认知、对职业的认知,就要求我们不能心存侥幸、马马虎虎、粗糙编码和上线。我们实际上通过各种案例发现,很多一线的研发同学丝毫不尊重用户进而造成引起恶性的线上事故。比如未经测试直接上线、发布后不管不问系统监控情况、业务出现问题后无法联系到相关的开发同学等等。


稳定性治理机制


在完成了自己对于故障的影响面认知程度之外,现在就是到了我们重点环节,就是要建立一整套完整的制度来保障稳定性。



  • 大盘和监控

在整个稳定性的保障里面,我觉得监控和告警是最重要的,因为如果没有了监控和告警,就无异于盲人摸象,整个系统到底有什么问题,问题什么时候会发生。发生了以后是什么样的影响面都不知道的情况下的话,就等于一个瞎子。


所以在系统或者业务上线的时候,就要同时伴随着监控和大盘的上线,我们不允许一个新的模块上线却不存在对应的监控的情况。


一般来说整个监控体系本身应该是比较完善的,有硬件、软件和业务系统的监控指标。也有跟周期相关的大盘的监控指标,比如说和上周的同比,和昨天的同比等等。在很多时候还可以对中间件进行一系列完整的监控,比如说对于数据库的监控,对于缓存的监控,对于PC框架调用的监控等。


还有一些可以针对自己业务单个接口的监控,在一些比较特殊的情况下的话,还有针对关键字的监控,比如可以单独配置监控日志里的NullPoint,用来快速定位到某些具体的问题,目前开源的一些监控系统都具备了这种即时数据收集和展现的能力。


除了监控之外,还要配套的就是报警机制。如果系统出了问题,研发同学第一时间感知不到。监控就等于是白费的,同时根据故障的等级、接口的调用量,我们会配置不同等级的监控,比如说非常紧急的问题,会用电话的方式进行报警。稍微弱一点的可能用群或者用短信的方式进行报警。

【集团报警】[2022/12/28 02:26] mm-orchard-push[hsf消费者成功率]
[C] 共有1台机器[hsf消费者成功率]触发[CRITICAL]报警, 摘要:
* 3x.6x.5x.1xx 当前时间的值: 87.50% < 90%


租户: 应用监控,应用: mm-orchard-push
报警统计:首次触发

报警的通知对象一般是业务的负责人或者固定的值班告警群等。这种报警的目的是能够第一时间让应用的负责人能感知到故障,并且让业务或者应用负责人作为接口人,能快速地找到上下游进行应急处理。当然告警机制本身也是需要演练的,以防止通知机制由于各种原因失灵导致无法及时把问题同步给负责人。比如以前就发生过系统短信欠费导致开发负责人收不到短信的问题发生。



  • 日常值班

还有一个事前预防性的措施就是日常的值班,日常的值班也分了两种,一种是我们的早值班,早值班主要是在8点~10点,这一段时间可能大部分的开发同学都没有来到公司上班的时候,我们会要求至少有一位员工是在线上观察问题。这个观察问题可以是查看系统日志或者获取线上用户的投诉CASE。


这个机制的保障可以监控到一些时间错位的问题。比如我们昨天晚上的发布,客户流量比较少,没有触发用户投诉,到了第二天早上客户大量的访问系统而造成的不可用引起的投诉。早值班处理的问题也是一样,也就是要第一时间感知到故障的发生,能够进行快速的一个止血,突出的也是一个敏捷性。


其次就是我们日常的常规值班,我们产品发布后都会有一些的产品不可用的问题、产品难用的咨询以及线上非预期的问题,那么我们会以一个值班群的方式,让客户或者业务方或者合伙合作伙伴都拉到群里,有一些客户在发现了客系统不可用的时候,第一时间会把不可用的问题提到群内,我们在值班的时候就能够及时快速的去判断这个问题是否是变更引起的故障问题。


不管在早值班还是在日常的答疑群里面,我们碰到这些问题的话,都会评估是否有故障的风险,然后都会尽快的成立故障应急小组,执行相应的预案或者计划。



  • 演练压测

演练和压测是预防故障里面非常重要的一个步骤,也就是通过一些常规性的动作模拟用户的大量请求,可以帮助发现系统的漏洞,把系统的不完善的地方全部暴露出来。我们在压测和演练的时候,一般会选在流量低峰期,既能暴露问题,又不会大面积的影响线上的真实客户。


那为什么要频繁演练呢?那是因为我们整个互联网的系统都是经常会有迭代和更新的需求,当我们某一次演练系统没有问题之后,业务可能又发生了大量的变化,很有可能会有新的故障点或者风险点的注入,那么这个时候通过常规化的演练,就可以更早暴露问题。


我们压测和演练都常规化了,每个月至少执行一次压测或者一次演练,压测一般也会选择核心接口以及本个本代里面新增的重要业务接口。在压测期间,我们会关注到对于上下游的业务分的调用以及自身的性能压力,当压测到极限的时候,发现了当内存、CPU、数据库还是外部依赖的超时的时候,我们会停止压测并记录问题,并最终复盘问题,对于相关的不符合预期的问题就进行一个分析和治理。



  • 技术方案评审

对于如此大流量的系统,我们要求所有的稍微大一点的需求变更,我们都要走完整的技术方案评审。因为有时候一个不合理的架构设计会导致故障频繁并且难以根治,架构的优雅性决定了故障的底线是高是低。


技术方案评审除了对于整个业务的ROI(投入产出比)进行一个通晒和判断之外,我们还会要求技术方案有完整的稳定性方案。


这个稳定性的方案一方面是要求对于现有的技术选型,要评估它是否会引入直接的风险点,比如说我们引进了一些新的缓存系统,那么缓存系统的容量能不能符合要求?缓存系统对我们业务保障的SLA又在多少?


除了对于系统方案的调研之外,我们也要求要有配套的保障的监控体系,比如我们这次引入的业务迭代有没有相关的监控和大盘?


其次就是要有业务开关和灰度策略。我们要求所有的核心功能上线都必须要有开关和灰度的方式,能够充分降低业务风险。而实际上表明我们对于这么大流量的情况下的话,用灰度是非常好的一个方式,灰度实际上就是把整个新的功能暴露在一小批用户并且我们去验证这些小批用户的可用性。


我们很多时候都发现我们在刚刚灰都了一批用户的时候,就发现了异常,我们及时的就会回滚和修复,这样就避免了把所有的用户暴露在故障和不可用的功能里面。



  • 故障应急机制

没有完美的系统,哪怕你的代码编写的再好,你的测试再完善,都可能会有遇到一些突发情况。比如非预期的流量、比如底层的网络超时、比如硬盘故障等。


所以我们成立了故障的应急机制。不管是发生了系统的自动告警,还是用户投诉,我们值班的同学或者业务的负责人能够第一时间感知到这些错误,并且能够快速得升级,按照SOP流程成立应急小组并把故障风险上升到指定的层级。


应急小组的形式往往是一个钉钉群,在必要的时候,我们会直接呼起电话会议,把上下游和受影响的团队都会全部拉上,快速的进行一个故障的初步判断以及止血方案的沟通。


所以我们的应急消防要求的特点就是要敏捷,能够快速的对故障进行响应,因为你只要响应的时间提前一分钟止血,客户受影响的时间就短了一分钟。很多大型公司会有保障制度,比如在指定的时间内完成对故障的处理,可以直接降低故障等级,也体现了公司的文化和价值倡导,即出问题不可怕,如果能快速止血问题,就是值得鼓励的行为。


因此我们在整个部门里面也要求做到1-5-15,也就是1分钟感知到故障5分钟定位的问题15分钟解决问题。当然在实际的过程中很难对于所有的故障都做到1-5-15,但是这是我们系统治理要持续追求的目标。



  • 紧急预案

我们的一些核心功能在上线的时候,我们都要求有紧急的降级预案,比如说当我们上线的功能发现了极端不可用的情况下的话,能否快速的止血?比如我们的产品就有一个非常好的全局降级计划,就是我们的服务端接口或者我们依赖方发生了大规模不可用的情况下的话,我们有一个紧急预案就是可以一键降级的缓存,那么客户就能够直接访问他的客户端缓存,这样的话就给了我们留下了很多时间去检验和修复问题。


紧急预案包含有很多方式,比如对于某些接口设置限流,在无法快速解决问题的时候,可以通过限流来保护系统,尽量把影响面降到最低。



  • 复盘

最后就是故障复盘。我们不能期待我们所有的欲望都是完美无缺的,正如系统一样,我们对于故障的认识和故障的处理也是需要反复迭代升级的。我们要求和鼓励复盘文化,不仅仅对影响到真实用户的问题进行复盘,也对潜在的问题进行复盘。


总结


首先我觉得对于一个研发同学来说,故障可能长期来看是不可避免的,但是我们还是要提升自己的对于故障的认知观,因为我们给客户造成了不可用,就是在一定程度上研发工程师的价值,那么我们应该追求写出非常优异的代码,能够写出非常鲁棒的系统,以及在系统出现了不可预期的问题下我们快速的去恢复用户的体验。


最后也不能因噎废食,不能因为怕引起故障就逃避写代码,这相信也不是公司请我们来的原因。而应该大胆创新、小心试错,在出现问题的时候,积极主动响应和治理,并且持续复盘进步,这就是一名优秀的工程师所要追求的素养。




作者:ali老蒋
链接:https://juejin.cn/post/7234436390280822841
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册