查看原文
其他

从故障中学习:稳定性设计和管理实践探索(下)

网易杭研 马宏展 网易杭州研究院
2024-09-10
云计算基础设施的快速发展使得分布式微服务架构成为可能,系统架构复杂度随之激增,运维难度也越来越大,稳定性面临前所未有的挑战。割裂式的组件保障再也没法满足业务快速增长的需求,保障团队逐渐从后台走向前台,同时结合实践经验开始反哺稳定性设计模式、工具和管理体系建设,并且开始转变为“面向自恢复”的思路,系统稳定性才得以大幅度提升。

本文结合理论与实践对稳定性建设做了一些总结,供各位阅读思考。本文为下篇,上篇见《从故障中学习:稳定性设计和管理实践探索(上)》

弹性工程-探索未知的未知


什么是弹性工程?


弹性工程既是跨学科的研究领域,也是多个来自如航空、医学、电力、航空运维和关键基础设施等领域的研究者社区。近年来,软件工程与运维领域也已介入这个已有20年历史的领域和社区,旨在创造和维持可以有效发挥弹性条件。弹性是持续的条件适应能力,或对不可预见情况的持续适应能力。它通过提前行动来应对未知的条件变化,保持对未知条件变化下的自适应能力。从未发生过的事情其实一直在发生,因此即使完全遵循了上述稳定性设计模式(应用的设计模式并不是越多越好,合适的场合用合适的策略即可),也无法幸免于未知条件下造成的事故。

如果说上面的设计模式是应对灰犀牛的好办法,那么针对黑天鹅我们必须通过不断创造变化的组合条件并在此之下验证系统的稳定性表现。很多人只有等出现重大事故时才会去调查事故原因,认为降级等微小的事件不值得深入了解,而实际上正是这些微小的事件蕴藏着更多关于故障的信息甚至产生新的知识,也很有可能因为一连串微小事件的组合,爆发出一场新的事故。为什么有些专家并不清楚是什么使得自己变成专家,而且通常他们也不知道自己知道什么,也是这个道理,专家知道的微小细节太多了,以致于他们认为这只是常识。

弹性工程与运维


我们最终为实现稳定性而设计,而系统的设计是使之具备弹性,最终达到稳定性目标。稳定性和弹性在本质上我认为是在不同视角下阐述的同一个东西,稳定性描述的是宏观状态,弹性则侧重于微观适应能力以达成稳态。

系统持续运维过程当中通常包含如下活动:
  • 对系统中的组件进行监控
  • 利用机会表现自己(非贬义)
  • 预测事故发生概率
  • 事故和故障响应
  • 预估未来运行情况
  • 学习系统特性
▲弹性系统模型(图片来自网络,侵删)

Rasmussen的动态安全模型阐释了系统如何在安全边界内正常运行而同时又处于不断向事故边界漂移的威胁之中。这张图很好地阐释了系统的弹性(Resilience),我们总结弹性为如下四点:
  • 监控Monitoring
  • 响应Reacting/Responding
  • 预测/适应Anticipating/Adapting
  • 学习Learning

这四点与我们日常运维过程保持了高度的一致性,弹性不仅仅描述了一种系统状态在正常和异常边界区域的变迁,同时描述了运维实践的一系列活动,这都是我们这里论述弹性的范畴。

最终我们为稳定性设计了多种策略,不仅限于系统,还在于人和组织,狭义稳定性只论述系统,广义稳定性更涉及到系统和人的一系列行为,因为人就是业务系统的一部分:
  • 我们给系统定义清晰的边界、层级和范式
  • 系统有自保措施
  • 系统资源有足够冗余
  • 系统有安全防护措施
  • 最佳实践和验证有确保机制
  • 系统组件有最终责任制

我们这么描述实现弹性:
  • 经受得住瞬时冲击
  • 快速平滑从失败中恢复
  • 优先处理高优先级任务
  • 识别并应对异常情况
  • 适应外部环境的变化

我们通过自己储备的知识提前预测、模拟故障,以此不断总结最佳实践和稳定性设计模式去设计系统稳定性,防患于未然,参考Netflix的混沌工程(Chaos Engineering),它的目标很清晰,在影响用户之前发现并解决风险,我觉得我们也一样。

团队组织


服务生命周期


产品在不同阶段面临的问题迥然不同。

1)混沌期
产品混沌期对业务领域模型尚不清晰,服务不会拆分太细,由于用户体量小,很少过度设计或直接用一套很复杂的分布式系统去支撑业务,稳定性的挑战并不大。这个阶段运维通常只需要响应计算/存储资源、基础架构搭建和日常运维需求便能满足业务需求。

2)快速成长期
步入快速成长期,经过市场的验证,业务领域逐渐清晰,团队更多人员的加入导致组织间协作困难,因此必然会动员一轮大规模的前后端分离和服务化拆分。拆分得到的数十上百个服务对运维来说难度加大,运维对每天的服务审批发布上线感到疲惫,但又担心一旦把发布交给没有运维意识和经验的开发将会导致稳定性失控的问题。这的确是一个恶性循环,运维每天忙于线上发布和咨询,导致新技术跟进缓慢,频繁的上下文切换导致问题处理效率变低,却又无法全权交给开发去处理日常运维事宜,整个组织的迭代效率严重受损。

此时不得不考虑策略上的转变,首先是以CI/CD工具链为主的DevOps文化上的转变,授权开发自助运维,从前置的运维审批操作上线到运维审批开发操作上线,再到后置的开发自助上线并自动通知到运维,最后到开发全权自助上线并负责日常运维和报警处理。但是这并没有解决问题,开发人员能力参差不齐,并缺失运维专业技能,面对一堆监控图表和系统日志惊慌失措不知从何处下手,直至运维人员召集各方共同进行故障排查,问题才得以止血。

过去为了利用专业化来提升效率,公司将运维与开发角色分开,而现今为了达成快速迭代目标迫使这两个角色重新整合,由于运维任务所需的技能通常与开发不同,这个事情不可能一蹴而就。面对大量的人工操作和报警,开发会不堪重负,进一步觉得运维工作没有价值。而减少报警和人工操作又需要开发与运维人员技能的融合,因此许多开发人员拒绝接受运维职责。很多产品声称可以减少DevOps的固有摩擦,但是却产生了更多的报警,引入了更多的系统噪音。除非有一个系统性的计划让每一个人接受培训并且在线上系统中得到磨炼,否则每个问题都只被团队中少有的专家掌握,即使这些专家乐于分享,面对大量的日常中断,他也会变得很少写文档,最终这些专家成为了一个团队的瓶颈。

3)成熟期
当产品趋于稳定,步入成熟期,一切开始步入正轨,我们强调精细化运营、强调线上质量、强调降本增效,我们开始关注过去从来不去关心的细小问题,以此来挖掘一切可能性。其中运维最接近资源最接近数据、最了解全局架构和故障本质,对于技术运营和持续的稳定性运维将发挥不可替代的作用。

以人为本


面对纷繁复杂的工具,如果开发看到的只是一条条扭曲的曲线和难以理解的数字并不能给线上稳定性带来收益,光有丰富的工具集与DevOps文化还不够,人员的技能也需要跟着持续提升。需要培养团队成为故障专家真的非常不容易,透过现象看到本质的能力也不是一朝一夕练就的。

开发运维自己的服务面临着运维经验和技能的问题,虽然建设了各种工具,但他们没有经过特殊训练便参与了运维值班。突然改变的职责让服务稳定性备受打击,团队开始变得泄气,同时开始互相推卸责任。开发缺乏核心运维技能,想努力学习跟上,却没有足够时间。其中一个问题便是没有正式授权责任,要建立这种线上责任机制,团队需要建立足够的运行线上系统所需的技能集合。

谷歌SRE总结出了的四大关键要素:
  • 度量:团队必须就做哪些事情可以提高用户满意度并消除与用户满意度无关的报警达成共识。使用SLO(Service Level Objectives)度量用户满意度,应当选取能代表用户满意度的边界指标来定义SLO,例如业务错误率,产品策划和客服通常很清楚这一点,要知道复杂系统总工作于部分降级模式,因此拿内部指标来衡量SLO并没有意义。实际上这有点类似于我们常说的业务监控,只是SLO只强调用户受损程度。通过SLO建立与用户反馈闭环对一个产品来说至关重要,这是发现问题的关键因素。我觉得SLO不仅仅局限于服务端,还应延展到用户侧客户端,毕竟客户端代表最终用户。
  • 可观察性:团队对线上健康度的感知必须始于用户症状,而不是潜在原因。重视故障定位。如果没有底层报警,如何得知SLO报警的问题原因是什么?我们需要故障根因定位能力,通过日志、指标构建全链路trace等可观察性工具来关联内部状态,仅测量并收集所有数据但却不分析数据不会对业务产生价值,场景化的分析和可视化至关重要。
  • 协作:团队必须确保彼此合作互相分享知识,并且能培训新成员。只定义好SLO并打造一系列监控报警工具并不会保证系统的连续性。最终需要人去运行系统、调试系统,并且随着系统迭代和新组件的引入,需要保持不断学习才能获得持续的系统洞察力。培训计划很重要,最常见的就是详尽的事故调查记录和事故总结。开发owner自己的服务并不是营造一个信息孤岛,而应保持开放,允许团队成员与团队外成员都可以提问题,只有这样才能进一步理解事故本身,并且更全面了解不同人针对事故的观点。跨团队的协作沟通不仅仅包含上下游关系,还可以包含多个职能角色,例如客服、开发和SRE。
  • 风险分析:团队需要一个框架来确认风险修复的优先级别,使系统可靠度满足用户需求。提前预测并解决系统风险,识别并应用最佳实践形成稳定性解决方案,不断预知并化解风险。


中心化团队


Netflix的《自由和责任》企业文化深深影响很多公司的组织架构以及处事准则,非常值得其他企业学习,现在国内也有了译本《奈飞文化手册》。开发无需任何审批即可将新功能发到线上,同时他们也是服务的owner,包括线上运维的职责,这一点对开发来说绝对是自由的,也保证了新功能上线的速度。但是在数百个微服务,数不清的调用链路上,没有人跟踪整个系统所有的变更,如何保持线上稳定?

关键在于Netflix的一个中心化团队:CORE SRE团队,这个团队由少数几个非常有经验的SRE以及系统工程师组成,他们是真正的故障专家,甚至可以称得上是服务的中枢神经。CORE SRE尽可能多地了解系统整体,并且懂得运用他们的知识来让系统得到更高的可靠性和可用性。他们理解事故本质,能观察到事故和运维中的种种通用模式,并且他们将这些模式变成工具和最佳实践来最小化事故影响或阻止事故发生。

事故发生时,SRE经常是第一个响应的人。他们深入排查事故,决定事故等级,确定哪些人应该参与进来止血,这些人可能是服务owner或者是第三方服务提供方,同时SRE会决定采用哪种流量迁移策略,比如迁移到另一个可用区,因为SRE是对系统整体最了解的一群人,他们能很快理解事故的发生原因,因此我们得以在大范围影响用户之前解决问题。

在事故和日常运维中挖掘通用模式,事故过后SRE会问一系列问题,例如:
  • 事故原因是什么?
  • 如何避免事故?是否遵循了稳定性最佳实践?如果遵循了稳定性最佳实践,是否可以避免本次事故?
  • 避免事故需要做哪些跟进工作?
  • 有没有可以提升故障排查速度的点?
  • 有没有能使事故影响面变得更小或者影响时间更短的工具?
  • 这个事故以前发生过么?是不是一种事故典型?
  • 事故处理过程中有没有错误决策导致事故影响时间变长或事故影响面变大?

通常会为核心业务团队配置SRE,便于更好地理解业务方痛点并对齐目标来直接提升工具化等能力,并且直接在业务线落地最佳实践。同时SRE通过在公司发表最佳实践、常规课程和准上线服务指导准则等方式来动员积极性。

在这其中运维工具和监控系统扮演了一个很重要的角色,CORE SRE强调定义好的指标的重要性,并且保证及时更新,然后将它们放到直观的大盘上面,并形成可行动的报警,并持续改进。

探索展望


本文虽侧重于稳定性,但也论述了面向用户的稳定性协作方式,一切始终以用户价值为依归,提供持续、高效、闭环的生产交付和运维能力,唯一目标就是为了让业务变得更好。

作者简介:马宏展,网易杭州研究院资深应用运维工程师,目前主要负责网易云音乐的稳定性体系建设等相关工作。2012年于中南大学计算机系毕业后入职迅雷,从事过系统运维、应用运维等工作,积累了丰富的大规模集群运维经验。2015年加入网易,曾负责网易新闻、网易云音乐等产品运维,有着丰富的分布式系统运维经验,同时经历过多年的产品一线救火,拥有对故障根因敏锐的洞察力,具备对性能和稳定性独到的见解。

继续滑动看下一个
网易杭州研究院
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存