是不是经常会遇到,有人在群里@你,告诉你你的系统出故障了,你在犹豫是不是真的出故障的同时还得慌乱地去查找?
老板问你系统现在到底健康与否,能不能快速给个判断,你却不敢断言?业务方说你的系统有问题,但你认为没问题,又无法自证?
这一切都源自于你的系统没有做好监控和告警:
没有监控或者没有一个好的监控,导致你无法快速判断系统是不是健康的;
没有告警或者没有一个精准的告警,当系统出问题时不能及时通知到你,并且告诉你哪里出了问题,影响是什么以及具体怎么解决。
一、监控告警为什么重要?
除了在上面提到的几个常见的场景,监控告警在我们保障系统的稳定性和事故快速恢复的全周期中都是至关重要的。这里提到了一个事故全周期的概念,它包含发现、定位、解决3个阶段,其中快速发现和定位是关键,而这部分主要依靠的就是监控和告警,解决问题也需要依靠监控和告警提供的具体的信息。
所以它关乎我们是否能发现或者快速的发现,定位和解决事故。特别是在业务高峰期,早一分钟解决就能减少很多损失,如果一个事故出现较长时间没有解决,甚至没有定位,将会直接影响用户的实际使用体验,这对公司形象和业务产生的影响与损失都是不可估量的。监控告警的重要性也就不言而喻了,可以那么说做好了监控告警能事半功倍。那监控和告警应该怎么做呢?
二、监控与告警体系该怎么搭建?
监控的定义就是监测和控制,监测某些事物的变化,以便进行控制。在常见的软件系统中,大多分为四大观察类别:
- 业务逻辑:项目所对应的服务及其承担的业务逻辑,通常需要对其进行度量。例如:单量,库存量。
- 应用程序:应用程序。例如:统一的基础框架,接口耗时,接口QPS。
- 硬件资源:服务器资源情况等。例如:CPU Load,内存使用量。
- 网络情况:比如网络丢包情况等。
1、明确监控告警的目标
要想让监控发挥它本有的价值,那我们必须先明确做监控的目标是什么。从现实层面出发,做监控的初衷,就是希望能够及时的发现线上环境的各种各样奇奇怪怪的问题,为业务的正常运转保驾护航。因此整体分为下图四项:
- 预测故障:故障还没出现,但存在异常。监控系统根据流量模型、数据分析、度量趋势来推算应用程序的异常趋势,推算可能出现故障的问题点。
- 发现故障:故障已经出现,客户还没反馈到一线人员。监控系统根据真实的度量趋势来计算既有的告警规则,发现已经出现故障的问题点。
- 定位故障:故障已经出现,但未找到具体故障位置,此时是需要协调公司内的多个组件,例如:链路追踪系统、日志平台、监控系统等,来定位故障点。
-
故障恢复:出现故障后,我们根据SOP或者其他方式(hotfix等)来恢复故障。
2、确定具体监控指标
有了目标,下一步我们就是要确定监控什么,监控哪些指标。这些在业内其实是有优秀的经验可以借鉴的,给大家介绍两个概念,希望可以给大家一些启发。
2.1 基础监控指标——黄金指标
《Google SRE 运维解密》 总结出了 4 个黄金指标,在业界广为流传和借鉴:
1)延迟:服务处理某个请求所需要的时间。
- 区分成功和失败请求很重要,例如:某个由于数据库连接丢失或者其他后端问题造成的 HTTP 500 错误可能延迟很低。因此在计算整体延迟时,如果将 500 回复的延迟也计算在内,可能会产生误导性的结果。
- “慢” 错误要比 “快” 错误更糟糕。
2)流量:使用系统中的某个高层次的指标针对系统负载需求所进行的度量。
- 对 Web 服务器来讲,该指标通常是每秒 HTTP 请求数量,同时可能按请求类型分类(静态请求与动态请求)。
- 针对音频流媒体系统来说,指标可能是网络 I/O 速率,或者并发会话数量。
- 针对键值对存储系统来说,指标可能是每秒交易数量,或每秒的读者操作数量。
3)错误:请求失败的速率。
- 显式失败(例如:HTTP 500);
- 隐式失败(例如:HTTP 200 回复中包含了错误内容);
- 策略原因导致的失败(例如:如果要求回复在 1s 内发出,任何超过 1s 的请求就都是失败请求)。
4)饱和度:服务容量有多 “满”,通常是系统中目前最为受限的某种资源的某个具体指标的度量,例如:在内存受限的系统中,即为内存;在 I/O 受限的系统中,即为 I/O。
- 很多系统在达到 100% 利用率之前性能会严重下降,因此可以考虑增加一个利用率目标。
- 延迟增加是饱和度的前导现象,99% 的请求延迟(在某一个小的时间范围内,例如一分钟)可以作为一个饱和度早期预警的指标。
- 饱和度需要进行预测,例如 “看起来数据库会在 4 小时内填满硬盘”。
如果已经成功度量了这四个黄金指标,且在某个指标出现故障时(或者快要发生故障)能够发出告警,那么从服务的监控层面来讲,基本也就满足了初步的监控诉求。也就是可以做到知道了出了问题,是一个从 0 到 1 的起步阶段。
2.2 核心监控指标——指南针指标
一般的情况下,黄金指标确实是非常重要且通用的指标,是每个系统都是必须要有的基础监控。但是对于一个复杂的业务系统来说,黄金指标这些通用的指标是不足以或者不能精确的反馈业务系统的核心价值的。每个业务系统的业务架构都不同,当然衡量业务系统的指标也应该是不一样的。
因此我们B站在实际情况中提出了“指南针指标”的概念:
- 指南针指标是系统对业务的核心价值体现,指南针指标同时也体现系统的健康与否
- 指南针指标的波动,一定意味着业务出现波动,业务出现问题,指南针指标一定异常。同时,一旦建立了指南针指标,每天就要关注自己的指南针指标:
- 出现波动需要给出解释
- 要对指南针指标设置告警
指南针指标不能很多,最好就一个指标,如果实在难以定义成一个指标,也不要超过3个,而且尽量精确简洁明了。对于技术管理者来说,指南针指标非常重要,他可以每天通过查看自己团队负责业务的指南针指标,提前预知一些风险和当前团队服务的健康情况。这也是为什么我说指南针指标不能太多,否则会让人抓狂。
以上是我们给出的指南针指标的定义,接下来举个详细的例子方便大家理解:对于弹幕系统来说,弹幕成功率就是指南针指标。这里需要解释一下,这是一个业务指标不是一个技术指标。弹幕往往涉及到风控,登陆等业务逻辑,比如在发送弹幕的时候被风控了而导致没有成功,在业务上我们不认为是发弹幕失败了,因为他不是弹幕系统本身的原因,而是跟风控系统的规则相关。同时弹幕发送耗时在这里我们也不算做是指南针指标,因为在发弹幕场景,往往是异步的,用户是能接受一定程度的延时的。如果延时有一定增长但是又在某个范围内,实际上时并不影响最终的结果,所以弹幕发送耗时这个指标不是指南针指标,但并不是说他不重要,他还是可以作为一个系统的核心指标。
2.3 日志监控
其实除了系统指标的监控,现在日志监控也是经常用到的。对错误日志进行监控和告警是解决故障的重要因素。日志监控跟具体的业务相关性比较大,这里给出的建议是:
- 错误日志量要有监控
- 核心链路上易出问题的地方务必设置日志监控和告警
3、结合监控设置合理的告警
监控往往并不是单独使用的,会有对应的告警设置,因为大多数情况下,大家都不会一直盯着监控,那样耗时又费力,所以如何合理的设置告警就成了关键。
3.1 一些实用的告警原则
再好的监控体系,闭环做不好,就无法发挥出很大的作用。因此我们给告警设置了一些实用的原则:
- 告警不要太多,否则会导致“狼来了”。
- 告警出现时,应当要有具体的操作,或者SOP。
- 不需要人工响应/处理的告警规则,应当直接删除。
- 告警信息应当有告警级别,影响面,如何处理等。
简单来讲就是告警要少要精确,事件需要解决,处理要人工介入。
3.2 故障等级与告警设置
定义故障的等级,在B站我们除了使用损失pv、收入来定义故障等级,故障的持续时间也是很重要的一个指标,对于一个核心服务,如果:
- 故障时间超过40分钟,属于P0事故;
- 故障时间超过30分钟,属于P1事故;
- 故障时间超过20分钟,属于P2事故;
- 故障时间超过10分钟,属于P3事故。
因此如何让事故在短时间内解决其实也是在考验我们告警设置的能力。前面我讲过事故全周期的概念,其中发现和定位其实很大程度依赖于告警,特别是发现故障。所以告警怎么设置,这里有几点可以供参考:
- 告警分级别,根据严重性,我们可以分为:提示,预警,严重,灾难
- 告警分原因
- 告警要有解决方案
如果是日志告警,我们还需要加上:
- 输入和返回参数
4、明确告警的人员和方式
4.1 渐进式告警到负责人
告警给谁?这是一个需要斟酌的问题,在告警的规范上,要尽可能遵循最小原则,再逐级上报。也就是先告警给 on-call 人,若超出 X 分钟,再逐级上报到全业务组,再及其负责人,一级级跟踪,实现渐进式告警。逐级上报的数据来源,可通过员工管理系统来获取,在员工管理系统中有完整的上下级关系(类似 OA 审批上看到的流程节点) 。
4.2 告警投群
往往还有另外一种情况,就是服务负责人不能立马看到告警,针对这种情况我们可以提前准备告警群,把告警投入小组的群里,这样群里的其他同学也能看到告警,帮负责人处理告警或者提醒负责人处理告警。
4.3 告警拉群
对于一些核心服务的灾难级别告警,我们可以使用告警拉群的方式,因为过往的经验告诉我们出现事故时不少时间都花在拉人进群上,而且当核心服务出现灾难级别告警就意味着核心系统出现了故障,有必要直接拉群进行故障处理工作。
三、监控告警平台的搭建
监控告警应该有自己的一套流程与标准,一般会通过平台搭建的形式来落实与运营。在这里主要给大家介绍一下业内常用的两个监控告警平台:Prometheus和CAT,此外还会再给大家介绍一个日志监控和告警平台ELK。
1、Prometheus
Prometheus 是一款基于时序数据库的开源监控告警系统,基于golang。Prometheus 的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。Prometheus 提供了从指标暴露,到指标抓取、存储和可视化,以及最后的监控告警等一系列组件,整体架构如下:
Prometheus Server:用于收集指标和存储时间序列数据,并提供一系列的查询和设置接口。
Grafana:用于展示各类趋势图,通过 PromQL 从 Prometheus 服务端查询并构建图表。
Alertmanager:用于处理告警事件,从 Prometheus 服务端接收到 alerts 后,会进行去重,分组,然后路由到对应的Receiver,发出报警。
Promethus有以下特点:
- 多维度数据模型,一个时间序列由一个度量指标和多个标签键值对确定;
- 灵活的查询语言,对收集的时序数据进行重组;
- 强大的数据可视化功能,除了内置的浏览器,也支持跟 Grafana 集成;
- 高效的存储,内存加本地磁盘,可通过功能分片和联盟来扩展性能;
- 运维简单,只依赖本地磁盘,Go 二进制安装包没有任何其他库包依赖;
- 精确告警;
- 非常多的客户端库;
- 提供了许多导出器来收集常见系统指标;
- 可以通过中间网关进行时序列数据推送;
- 通过服务发现或者静态配置来发现目标服务对象。
详细可见:https://zhuanlan.zhihu.com/p/...
2、CAT
CAT是基于Java开发的实时应用监控平台,为美团点评提供了全面的实时监控告警服务。CAT 作为服务端项目基础组件,提供了 Java, C/C++, Node.js, Python, Go 等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框架,RPC框架,数据库框架,缓存框架等,消息队列,配置系统等)深度集成,为美团点评各业务线提供系统丰富的性能指标、健康状况、实时告警等。
详细可见:https://github.com/dianping/cat
3、ELK&ElastAlert
3.1 ELK
ELK是 ElasticSearch、 LogStash、 Kibana 三个开源工具的简称,现在还包括 Beats,其分工如下:
- LogStash/Beats: 负责数据的收集与处理
- ElasticSearch: 一个开源的分布式搜索引擎,负责数据的存储、检索和分析
- Kibana: 提供了可视化的界面。负责数据的可视化操作
基于 ELK 可以构建日志分析平台、数据分析搜索平台等非常有用的项目。
详细可见:https://blog.csdn.net/Ahri_J/...
3.2 ElastAlert
但是对于错误日志的监控ELK架构并没有提供,所以我们需要使用到第三方工具ElastAlert,来帮助我们及时发现业务中存在的问题。ElastAlert通过定期查询Elasticsearch,并将数据传递到规则类型,该规则类型确定何时找到匹配项。发生匹配时,将为该警报提供一个或多个警报,这些警报将根据匹配采取行动。详细可见:https://mp.weixin.qq.com/s/W9...
四、B站的实践案例
讲了那么多方法论,可能大家还是没有一个特别清晰的概念,我这边就拿B站的实际应用监控来给大家具体说说,先给大家展示一下。
1、黄金指标类的监控
服务常用指标监控:
服务接口监控:
依赖的服务监控
依赖的组件监控
2、指南针指标类监控
弹幕指南针指标
相关下钻指标
那监控其实是我们安插在应用身上的眼睛,它做的事情是观察和收集,要怎么有效利用这些数据指标,还是得靠人。仍旧以前面的弹幕发送成功率这个指标为例,来说说B站的告警是怎么做的。
一般我们会根据业务需求设置一些告警触发条件,当成功率低于一定数值就会产生提示/预警,我们采取的是告警投群的方式,这种方式的好处前面也有提,方便协作也不至于遗漏重要告警的处理。
告警拉群的方式B站也在积极尝试中,希望能够达到当核心服务的灾难级别的告警出现,可以直接触发拉群,将相关服务负责人及其上级、运维相关同学自动拉入群中的一个效果,目前该功能B站还在研发中。
五、总结
监控告警的最佳状态就是实现“一五十”,所谓“一五十”,就是指我们能一分钟发现事故,五分钟定位,十分钟解决。相信这也是众多企业SRE的想要达成的目标,希望今天给大家讲的这些内容能够帮助大家实现精准的监控和告警,把问题扼杀在摇篮里,减少故障带来的业务损失。
👉更多精彩内容点击【故障经验库】