草庐IT

虎牙SRE谈可观测:如何做到比用户和老板更早发现业务异常?

TakinTalks稳定性社区 2023-03-28 原文

一分钟精华速览

可观测能力是指在复杂的软件系统中能及时、准确感知到服务状态,特别是异常或故障的发生,确定异常的影响范围、异常部位边界、判定异常点位、并由相关人员或软件做出准确决策的能力。
本文作者结合虎牙SRE实践及20余年架构、研发、运维经验,重点讲述如何设计和建设观测能力,做到分钟级感知故障、定位和快恢。

作者介绍

《SRE原理与实践》作者 张观石
TakinTalks稳定性社区专家团成员,前虎牙SRE负责人,资深运维专家和架构师,拥有20年软件开发、架构、运维、SRE经验。历任项目研发负责人、SRE负责人、架构师,事故管理委员会委员、基础保障部架构师委员会委员。熟悉基于微服务架构的直播业务、音视频业务、海外直播业务的稳定的保障体系。在混合多云架构、可观测性、预案、变更管控、AIOps等SRE领域有深入研究和丰富经验。参编信通院《信息系统稳定性保障能力建设指南》。

温馨提醒:本文约5000字,预计花费10分钟阅读。
后台回复 “交流” 进入读者交流群;回复“2251”获取课件资料;

背景

在以前,运维团队一般都是做后端运维,比如基础监控、操作系统、中间件、拨测等等,但是互联网平台以业务为中心,以用户为中心,平台的功能服务、质量和用户体验等是关键的目标,仅仅关注后台系统的可用性是不够的,以传统运维的视角来解决故障、做监控会比较被动。

运维想主动介入到业务中,我认为建设可观测能力是一个很好的办法,融入研发和业务部门的视角,甚至用户的视角,通过可观测性建设把SRE的工作推进到移动端、业务侧、微服务的内部,甚至可以用来度量相关的能力,真正深度参与到提升业务连续性中。作为SRE来讲,从用户的角度来保证业务的稳定性和质量是最终目标。

一、观测能力如何帮助快速定位?

这里我先从虎牙的一个实际案例,来展开讲讲观测能力是如何帮助快速定位的。

发现:

当一个业务出问题时,很可能会有大量微服务出现异常,但你可能不知道是哪一个。上图通过肉眼来看,大概能够知道它的原因——调用量突然大幅度上升,上升到一定程度就开始有部分调用超时了。
那么,告警里是否能把这种“肉眼可见”的信息体现出来?

告警:

这是其中一个告警信息,会呈现错误类型、调用方法、调用接口、被影响实例、具体日志错误异常等等,还会关联到这个服务的错误明细页。这个告警信息就可以比较容易做初步判断,通过链接进去能较快进行二次判断。

定位/分析:

当微服务告警很多时,我们还希望进一步了解,错误是否在某条链路上、是否都属于某一个业务的服务,以及它是怎么传播的、影响了哪些链路、哪些服务、哪些实例、哪些没有被影响、失败的调用源头是哪里、起点是哪里等等。

在这个调用链中能看到,这次告警影响了哪些链路、哪些服务、哪个是最根本的源头,通过调用链还能看到节点,而且能够和日志的详细信息做关联分析,接口错误次数、失败率、失败次数都能看得到。

告警会同步黄金指标存在的问题,并直接告知根因,比如,故障是哪个平台的、返回码是什么、占比是多少等等,如果有对应的预案,也会关联到对应的预案,这对我们分析问题有很大的帮助。

二、为什么要建立可观测能力?

2.1 我理解的可观测性

可观测性的本质,我理解是系统内外部状态的数字化表示。我们的系统是一个实体,它的状态可以通过一些直观的图表、文字、曲线表示出来,工程师可以通过观测系统看到系统的结构、状态以及变化。通过这套体系,在一个比较复杂的系统里找到变化的根源,并可以解释为什么会发生这些变化、变化的相关性、变化的逻辑性等等,这是可观测性的本质。

可观测性也会给SRE工作带来诸多收益——
第一,系统的稳定性、可靠性确实会有很大的提升。
第二,通过观测体系建设,比如数据上报、数据应用,可以让SRE工作推行更加顺利。SRE通过观测性建设能够成为整个团队里比较关键的力量,可以参与到很多工作中去,和其他团队尤其业务团队的工作结合更加紧密。

2.2 监控观测范围的扩大过程


从传统的“以后台系统为中心”到当前的“以业务/用户视角为中心”,可观测性能力的建设是运维工作变被动为主动非常重要的抓手。

举个例子,一位虎牙主播正在直播时,如果网络抖动或其他原因,观众反馈卡顿了,之前的处理办法是主播、运营、主播端技术这三方进行沟通,上传日志,然后工程师后端做分析,或者让主播尝试重启。在接入可观测系统后,通过主播上报的数据、接入服务、后台的监控数据等,就能看见整个直播间的运行状态,不再需要主播和运营找研发侧做沟通。直接通过数据做对比实时分析,就能够较快找到问题,把里面的数据结合起来做分钟级的告警。

在扩大期建成了统一的观测系统后,在核心期还可以做到统一规范、上报、存储、展示,充分利用这些数据互相关联,引入大数据和AIOps的能力,快速感知、分析、诊断问题,同时利用这些数据来度量业务的质量以及整个稳定性工作的结果。

2.3 监控观测技术的演进


监控观测技术大家都很熟悉了,很多企业也都在往统一观测这个阶段去演进,比如全景监控、全链路立体、立体监控、融合监控等等叫法不一。

第四个阶段——综合感知能力,我觉得是未来的发展方向,即我们要做的不只是观测,更要强调综合的感知能力,不管是业务的感知,还是智能决策,比如自愈、触发容灾等。

三、如何建立分钟级的发现、定位和修复能力?

3.1 确定发现/定位/修复 需要的能力

3.1.1 发现故障

发现问题一定要监控业务,从用户最直观、最重要的服务开始监控。

在以前有一个比较尴尬的情况,传统方式只做后台监控,但工程师发现一个故障其实主要依赖软硬件的监控,还有系统后端服务的监控。这会导致用户、运营甚至老板发现问题了,但工程师却看不到异常指标;又或者知道某个微服务出问题了,但不知道对用户的影响有多大,即监控不能代表用户访问业务的质量。还有,在传统的方式里,工程师需要配置、维护大量指标监控,随着系统和对接人员发生变化,很难保证不出错。

所以要从用户最直观、最重要的服务开始监控,比如,辽宁省移动运营商的一部分用户看不了直播,在用户、云厂商发现之前,观测系统是否能提前发现问题,并发出告警信息这点很重要。

3.1.2 定界定位

评估故障影响范围、严重程度等,这要求系统有很强的分析定界能力。

再举个例子,当用户状态的全局成功率下降了2%时,观测系统需及时找到问题点、快速确定范围,并找到问题的原因、影响用户、用户状态等等。

而传统的方式是分散建设,团队各自建设自己的监控系统,比如基础设施的有一套、容器的有一套、日志的有一套等等,各团队为了小团队的工作,构建了大量这样的监控系统,在各类公司中这样的监控系统基本不少于四套。如果监控数据割裂,则很难快速确定根因,比如,服务器上出了故障,要找微服务的监控;微服务的故障,要跨系统找基础设施、网络、日志的数据,这样的效率是非常低的。

3.1.3 决策修复

所有的监控数据必须上下关联做统一建设,并结合算法分析,才能做出更快更好的决策。
在监控数据统一的基础上,没有数据的需要补充数据,有数据的要充分利用数据,综合利用算法的能力,尽快确定影响范围,做初步的定位,通过告警的方式告知根因。再进一步推荐预案,直接关联到某个执行的预案里,只需一键执行或者简单操作即可,最终是希望能做到自愈。

3.2 从14个环节中发现改进点

为了更快修复故障,我们把故障的生命周期展开来看一看。

发现、定位、修复三步展开来,可以分为图中的14个环节。这张图摘录自我的新书《SRE原理与实践》,这部分内容我在书中有详细介绍。

在这些阶段里需要尽量把工作往前做,比如在苗头阶段能够看出趋势就告警出来,不会出现大量的报警淹没,这样能做到更早、更主动地发现问题。

举个例子,还是以虎牙直播为例,在看直播时卡顿或者打不开,大多数用户是不会反馈的,不爽的时候直接就换个直播间或直接走掉了。当我们把故障生命周期分成14个阶段后,就能够细致分析在哪个节点的效率是可以提高的,比如,在苗头阶段能否发现、通知确认阶段能否缩短时长、告警是否可以更加敏感、定位是否可以更加高效、根因定位是否能更加准确等等,想尽一切办法来缩短整个MTTR(平均修复时长)。

3.3 明确度量要求

故障过程的度量要求这里有2个参考,一个是阿里的“1-5-10”,即1分钟发现,5分钟定位,10分钟修复;二个是虎牙的“2-3-5”,即2分钟发现,3分钟定位,5分钟修复。

3.4 建设可观测性的3个要点


第一点,要做统一的规划建设,包括统一采集、规范、上报、存储、UI/API、公共算法等。

第二点,建议把影响用户的关键指标作为业务的黄金指标,并和业务研发、老板达成一致,从用户侧上报这些关键的质量指标,并为每个黄金指标配置一套完善的监控、分析、排查、诊断甚至修复预案的能力。

第三点,以终为始,通过黄金指标的建设,建立起一套度量的体系,一方面度量业务本身的质量、稳定性,另一方面可以度量整个过程,比如首发率、监控告警率、告警漏告率,以及发现时长、定位时长、修复时长等等,形成指标体系,以此在公司内部打通上下认知。

3.5 建立可观测性-指标范例

下图是虎牙在某个微服务的监控指标,供参考。

3.6 案例:可观测应用

下图是可观测帮助发现能力短板的又一个案例。分析此故障中,故障发现能力存在严重问题,工程师升级实例失败没有发现,也没有告警,而是通过调用此服务的上游业务告警后才发现。

以上就是可观测性建设的整体思路和方法,具体的实践细节在《SRE原理与实践》的第四章中,有较大的篇幅重点来讲,包括一些实践案例在书中都有详细的讲解。

四、实践案例:AIOps提高故障定位效率

AIOps最大的作用,我认为是可以帮助理解海量的数据,在海量的数据里找到相互间的因果关系、正相关性等逻辑关系。比如,指标抖动后的分析各个维度之间的相关性、逻辑性,并能够通过算法分析。在过往可能每个维度都需要人工分析,而AIOps算法能够自动化地做这些分析。

4.1 观测帮助快速发现、定位、快恢


当某直播间总卡顿率出现异常时,需要确定是哪个维度及组合中的指标(集合)导致的。如图可以看出有三个线路都有卡顿,按码率只有一个1200,按P2P有唯一的卡顿,这样通过人工来看,可以大概得出结论是按码率和P2P这个组合导致的卡顿。基于这个长期的经验,SRE团队研发了卡顿多维度更新定位的算法,同时联合多个部门闭环解决。

如上图所示,我们在主播端加了一个智能的卡顿反馈按钮,点击卡顿时,后台就可以通过观测数据做算法分析,一部分确定是主播自己问题的,会反馈给主播并告诉主播如何修复,提供相应建议。另一部分通过分析发现是后台问题的,可以通过其他方式,比如切上行、切码率、切线路、切P2P等,做到部分自愈。无法自愈的部分,比较复杂的问题就会形成一个自动化的工单,进入工单系统中。

4.2 AIOps帮助快速定位:技术方案

对任意给定的叶子节点,采用了两个指标Influence Degree 和 Contribution Ability评价它和异常的相关性。
采用加权关联规则挖掘的方式自行挖掘维度之间的关系。
采用迭代定位的方式处理同一时刻有多个根因的情况。
最终基于原始数据分布排序输出推荐的根因。

4.3 AIOps帮助快速定位:效果

卡顿反馈按钮背后集成了AI卡顿定位模型,打通值班工单系统、一线&研发值班处理流程,最终主播卡顿平均解决时长由10分钟缩短到3分钟,时长明显缩短;

有1/3问题准确识别,能给主播提供修复建议;

工单总量下降50%,识别率达到80%;

所有Case经过多维度根因定位模型分析,Top1根因引发的报障由23%下降到了6%。

五、总结

以业务为核心进行,统一建设可观测性。在业务至上的时代,我们都要以业务为核心去做稳定性保障,而不是以技术工程师的视角认为只是保障IT系统或者软件。一个业务可能会涉及到很多微服务系统、庞杂的基础设施、庞杂的用户终端,孤立地只关注某个层面是不够的,必须要以业务为核心去把整个链路给串起来。
充分利用业务特点和AIOps算法,集成到发现和定位、判断决策的过程。不管定位还是修复,都需要尽量利用算法的能力
把分析结果与告警、预案等打通。让整个链路工作捋顺、上下游畅通。

添加助理小姐姐,凭截图免费领取以上所有资料

并免费加入「TakinTalks读者交流群」

声明:本文由公众号「TakinTalks稳定性社区」联合社区专家共同原创撰写,如需转载,请后台回复“转载”获得授权。

本文由博客一文多发平台 OpenWrite 发布!

有关虎牙SRE谈可观测:如何做到比用户和老板更早发现业务异常?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐