搭建一个通用监控告警平台,架构上需要有哪些设计
Posted 倾听铃的声
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搭建一个通用监控告警平台,架构上需要有哪些设计相关的知识,希望对你有一定的参考价值。
大家好,又见面了。
说到监控告警平台,大家应该都不会陌生,对于线上系统而言可以说是个标配,各个公司或项目也都会有搭建自己的监控告警平台的实际诉求。
当前比较主流的监控告警平台实现方案,很多都是基于Prometheus + Grafana + AlertManager
来实现的。但是实际使用的时候会发现不易实施:
-
在运维部署对接方面存在一些不便,接入新的被监控节点时需要到平台部署机器上去修改配置文件、甚至重启服务来生效
-
配置告警规则等也是基于xml配置,必须要到平台服务器上去添加文件,对于一个各项目通用的平台而言,显然不可能将后端服务地址暴露让各业务负责人员去自行修改服务器上的配置文件
-
Grafana
界面相对单一、可以用于看板或者大屏展示,但是一些公司内高度定制化的页面能力实现起来会比较麻烦(当然也可以基于Grafana
二次开发定制),或者想在公司已有的运维平台中深度集成,实现难度较大。
前段时间研究了下基于Prometheus
构建监控系统相关的概念,并以此为基准设计了一个企业级通用的监控告警平台的方案。这里分享一下架构的分析过程以及上述问题的解决思路。
平台与业务职责规划
既然是构建通用平台,就会涉及到平台与业务的职责划分的问题,这条线究竟按照什么尺度去画,究竟将平台做厚还是做薄,将直接决定了平台的整体定位:
- 平台做的太厚重,势必导致业务使用的约束增加、且定制化能力减弱,适用范围受限;
- 平台做的太轻薄,业务虽然有更多的主导权与定制灵活度,但也导致各个业务需要重复构建相关能力,平台将失去意义。
从构建通用平台的角度而言,很明显厚平台
方案更具优势,可以统一整个公司各个业务的监控水平、可以持续的汇聚能力、积累沉淀。
所以,最终选择采用厚平台
模式来构建:
- 集成数据存储、统计、告警策略、告警推送等能力,业务仅负责埋点数据上报即可。
- 告警能力扩展性强,全业务无差别共享
- 业务接入简单,但平台实现工作量较大
- 业务可以有限定制,但是需要基于管理界面上去配置规则,受平台规则支持度限制
用户场景诉求分析
先分析下对监控平台的一个整体的诉求情况、以及监控平台需要支持的一些核心业务场景。
从用户角度,收集下不同角色的人员的诉求:
-
管理人员:
- 掌控全局整体情况
- 可以按照不同维度查看(比如按照部门、按照项目、按照负责人等维度进行查看)
-
开发人员:
- 知晓自己负责的项目的状态
- 若有异常能第一时间收到告警通知
- 可定制自己项目的告警规则与告警接收人员
-
运维人员:
- 查看负责的所有机器情况
- 部署接入简单
- 中间件可以一键接入,不要有额外的部署安装操作
- 监控平台自身的稳定与可靠
总结下来,用户层面对系统的诉求点主要有:
能用:能查看整体情况、能划分权限控制、能接收告警 易用:业务接入简单、方便自定义规则
选型与整体设计
作为监控平台,当前主流的一个方案就是Prometheus + Grafana + AlertManager
的配套,本次方案也使用此常规配套。
关键设计点:
-
由于
prometheus
采用配置文件的方式管理数据采集、告警规则等,为方便使用,设计搭建配置界面与配套服务,负责web端修改配置,server端写入prometheus
配置文件中的逻辑、中间件探针自动启动部署等能力。 -
考虑到
prometheus
告警推送通道有限、因此设计了消息推送服务,提供rest
接口接收prometheus
的告警推送,然后转发到现有的微信推送通道中,实现在微信上接收告警。 -
通常
Prometheus
探针会部署到被监控的进程所在机器上,较为分散,维护难度较大。对于常见的各种中间件的数据采集探针,采用集中服务器部署的方案,通过web下发命令部署对应中间件的探针服务。
最终整体构建的全貌图如上所示,橙色的部分为使用开源组件实现,绿色部分为自行构建,作为辅助能力,打通平台的辅助操控能力,降低用户的使用门槛。
关键点设计
监控平台管理界面方案
作为与用户层面打交道的门面,管理界面端的实现既要承载用户维度的基本使用诉求,更是解决前述说的Prometheus + Grafana + AlertManager
使用配置与规则定制门槛过高的关键一环。
基于Prometheus
构建的监控平台中,很多都是标配了Grafana
作为界面展示。但是Grafana
作为通用开源组件,侧重点在dashboard
展示能力上,其余一些管理能力较为弱化。
所以在界面的规划上,采用的策略是继续以现有的运维平台界面为主,设计整合grafana
的dashboard
展示能力。也即对用户而言,入口都是运维平台Poral,一些规则配置、部署操作等统一由运维平台portal提供,只是点击查看某个项目的数据时,跳转到Grafana
展示。
分层、分组告警实现机制
作为一个监控告警平台,告警能力自然是最关键的一个部分。此部分使用Prometheus
已有能力。
具体实施时,为了实现告警的按需推送、精准推送,规划在Prometheus
配置采集探针数据的时候,为每个探针配置对应的标签数据,比如项目组、系统、模块、环境类型等等信息。这样就可以进一步按照项目组或者系统维度进行推送给相关人员。
此处规划是在prometheus
拉取探针服务的地方进行配置追加固定分组tag信息,而不是由各个探针的指标项中自己上报,主要也是从平台统一控制维度进行考量。
对接告警通道设计
Prometheus实现告警有2种可选方案:
- 对接
Prometheus AlarmManager
组件, 通过修改服务器上的本地配置文件,实现告警规则的设置; - 对接
Grafana
,使用Grafana
告警功能,直接在Grafana
的界面指标项中进行配置。
其实,不管是Prometheus AlertManager
还是Grafana
,其配置都需要遵循一定的规则,对于没接触过的人而言,还是有一定的使用门槛的,而且两种配置起来都很不方便,尤其是AlertManager
,还得登录部署服务器上去新增或修改配置文件 —— 这个作为一个平台,显然是不可接受的。
所以,从功能与便捷性角度考虑,选定使用AlertManager
实现告警能力。作为对其弊端的补偿,规划构建管理配置服务,并在平台统一Portal上提供无门槛易用的配置能力,如下:
用户通过界面上配置好之后,变更的配置文件经由管理配置服务中转,自动写入AlertManager
对应配置文件中,由此避免人为修改AlertManager
服务端配置文件可能引发的问题。
AlarmManage预置的告警通道主要有邮箱、钉钉、企业微信、或者webhook
等。出于可自由定制、以及后续可自由定制的角度触发,此处选择采用webhook
的方式:
- 新开发一个
webhook
告警接收服务,提供rest接口用来接收告警信息; - 对接收到的告警信息进行处理后,调用当前监控平台提供的微信告警推送接口,推送给用户。
部署与运维管理策略
基于Prometheus
的机制,数据上报采用探针的方式暴露相关接口,然后Prometheus
定时轮询拉取。
对于探针的部署,考虑可选常规模式
与集中模式
两种。
常规模式: 各业务、各中间件节点自行部署自己的探针服务。
集中模式: 各中间件的探针服务集中部署,打通web端配置逻辑,根据自动部署探针服务。
从实施工作量上进行评估,最终敲定混合使用两种模式:
- 中间件监控,采用集中部署,作为平台能力一部分,集中监管。
- 各业务监控,采用常规模式,各个业务自行定制提供探针服务并部署。
关于中间探针集中部署:
- 将各常见中间件的exporter包安装到服务器上
- 根据web传过来的被监控中间件的类型
- 执行命令,z启动对应探针
- 为了后续可维护,将启动命令写入脚本文件中,设定开机自启动
- 相关配置信息、每个exporter绑定的port信息以及监控的中间件信息,保存到DB中,便于维护。
高可用设计
作为一个用来监控其他服务是否正常的告警平台,其自身的高可用性显然是必须要考虑的事情。一旦监控平台挂掉,业务出问题可能就无法第一时间通知到责任人,很容易引发线上事故。
对整个平台的高可用设计,采用分模块不同的策略:
Prometheus 高可用:冗备方案。部署2套prometheus
进程,两套prometheus
采集相同的探针节点,拥有完全相同的配置数据。 可扩展:分片策略。当监控对象数量太多时,将监控对象分片,每个分片部署一套(2个进程)prometheus
服务,实现水平无限制扩展。
AlarmManager 高可用、可扩展:集群部署。多个prometheus
进程发送到AlarmManager Cluster
中的重复告警信息,最终只会有1条告警会被发送出去。
配置部署服务 高可用、可扩展:集群部署。部署多个进程节点,对外提供统一访问地址。
探针服务 非监控平台主体,不做高可用保证,宕机会有告警,满足要求。
总体回顾
回顾下整个方案的分析与设计过程,其实整体逻辑很简单,选型确定之后,根据选型结果,以及选型与目标诉求之间的差异度,考虑如何抹平两者之间的差异。也即所谓的“不忘初心、以始为终”。
按照上述策略搭建完成后,整体的监控平台的功能全貌为如下:
设计一个靠谱的监控告警平台
— 1 —
一套监控系统检测和告警是密不可分的,检测用来发现异常,告警用来将问题信息发送给相应的人。vivo监控系统1.0时代各个监控系统分别维护一套计算、存储、检测、告警收敛逻辑,这种架构下对底层数据融合非常不利,也就无法实现监控系统更广泛场景的应用,所以需要进行整体规划,重新对整个监控系统架构进行调整,在这样的背景下统一监控的目标被确立。
以前监控被划分为基础监控、通用监控、调用链、日志监控、拨测监控等几大系统,统一监控的目标是将各个监控指标数据进行统一计算、统一存储、统一检测、统一告警、统一展示。这里不作赘述,后面会出一期vivo监控系统演进的文章进一步说明。
上面我们说了监控统一的大背景。以前各个监控系统会各自进行告警收敛、消息组装等工作,为了减少冗余,需要将收敛等工作由一个服务统一做处理,与此同时告警中心平台也到了更新迭代的阶段,这样就需要建设一个对内部各业务统一提供告警收敛、消息组装、告警发送的告警平台,有了这个构想,我们准备将各系统告警收敛能力与告警发送能力下沉,将统一告警服务做成一个与各监控服务解偶的通用服务。
— 2 —
对于1.0时代的监控系统来说,如图1所示各个监控系统要先进行告警收敛,然后分别和老的告警中心进行对接,才能将告警消息发送出来。每一套系统都要单独进行维护一套规则,有很多重复功能建设,而实际这些功能具有高度通用性,完全可以建立合理模型对异常检测服务生成的异常进行统一处理,从而生成问题,然后进行统一的消息组装,最后发送告警消息。
图1 老监控系统告警流程图
在监控系统中一个异常从被检测出来到最终发出告警,有几个重要概念:
异常
在一个检测窗口(窗口大小可以自定义),一个或几个指标值达到检测规则定义的异常阈值,就产生一个异常。如图2所示,检测规则定义当指标值在一个检测窗口为6的检测周期内,有3个数据点超过阈值就认为有异常,我们简称这个检测规则为6-3,如图所示第一个检测窗口内(蓝色虚线筐内)只有6和7两个点的指标值超过阈值(95),不满足6-3的条件,所以第一个检测窗口没有异常。在第二个检测窗口内(绿色虚线框内)有6、7、8三个点的指标值超过阈值(95),所以第二个窗口就是一个异常。
问题
一个连续的周期内产生的所有同类异常的集合,我们称之为问题。如图2所示,第二个检测窗口就是一个异常,同时这个异常也会对应有一个问题A,如果第三个检测窗口也是一个异常,那么这个异常对应的问题也是A,所以问题和异常是一对多的关系。
告警
当一个问题通过告警系统将消息以短信、电话、邮件等方式告知给用户时,我们称之为一条告警。
恢复
当问题对应的异常不满足检测规则定义的异常条件时,就认为所有异常都恢复了,同时问题也认为恢复了,恢复也会发送相应的恢复通知。
图2 时序数据异常检测原理图
一个系统我们如何衡量它的好坏,如何提升它,如何管理它?管理学大师彼得·德鲁克曾说“你如果无法度量它,就无法管理它(If you can’t measure it, you can’t manage it)”。从这里可以看出,如果想全面管理提升一个系统,就需要先对它的各项性能指标有一个衡量,知道它的薄弱点在哪里,找到病症所在才能对症下药。
图3 运维指标时间节点关系图
图3是监控系统运营指标和对应时间节点关系图,主要体现了MTTD、MTTA、MTTF、MTTR、MTBF等指标与时间节点的对应关系,这些指标对于提升系统性能,帮助运维团队及早发现问题有很高的参考价值。业界有很多云告警平台也很注重这些指标,下面我们着重介绍一下MTTA、MTTR这两个和告警平台关系紧密的指标:
MTTA(Mean time to acknowledge,平均应答时间):
图4 MTTA计算公式
t[i] —— 监控系统运行期间第i个服务出现问题后运维团队或者研发人员响应问题的时间;
r[i] —— 监控系统运行期间第i个服务出现问题的总次数。
平均应答时间是运维团队或者研发团队响应所有问题所花费的平均时间。MTTA度量标准用于衡量运维团队或研发团队的响应能力和警报系统的效率。通过跟踪和最小化MTTA,项目管理团队可以优化流程,提高问题解决效率,保障服务可用性,提升用户满意度。
MTTR(Mean Time To Repair,平均维修时间):
图5 MTTR计算公式
t[ri] —— 监控系统运行期间第i个服务出现r次告警后服务恢复正常状态的总时间
r[i] —— 监控系统运行期间第i个服务出现告警的总次数
平均修复时间(MTTR)是修复系统并将其恢复到正常功能所需的平均时间。运维或研发人员开始处理异常,MTTR便开始计算,并且一直进行到被中断的服务完全恢复(包括所需的任何测试时间)为止。
在IT服务管理行业中,MTTR中的R并不总是表示维修。它也可以表示恢复,响应或解决。尽管这些指标都对应MTTR,但是它们都有各自的含义,因此,要弄清楚要使用哪个MTTR,有助于我们更好的分析理解问题。让我们简要地看一下它们各自的含义:
平均恢复时间(Mean time to recovery)是从系统告警中恢复所需的平均时间。这涵盖了从服务异常导致告警到恢复正常的整个过程。MTTR是衡量整个恢复过程速度的指标。
平均响应时间(Mean time to respond)表示从出现第一个告警开始到系统从故障中恢复到正常状态所需的平均时间,不包括告警系统中的任何延迟。该MTTR通常用于网络安全中,以衡量团队缓解系统攻击的效率。
平均解决时间(Mean time to resolve)表示完全解决系统故障所花费的平均时间,包括检测故障、诊断问题以及确保故障不再发生来解决问题所需的时间。此MTTR指标主要用于衡量不可预见事件的解决过程,而不是服务请求。
提升MTTA的核心是找对人、找到人,只有在最短的时间内找对能处理问题的人才能有效提升MTTR。
通常在生产实践过程中我们会遇到“告警泛滥”的问题,大量的告警出现时需要运维人员或者开发同学去解决,对于应激敏感的同学来说很容易出现“狼来了”的现象,只要收到告警就会很紧张,同时当大量的告警信息频发骚扰我们运维人员,会引发告警疲劳,体现为不重要的事件太多,最根本的问题较少,频繁处理普通事件,重要的信息淹没在汪洋大海中。
图6 告警泛滥问题图
通过上面两个重要指标的分析,我们总结出要从告警数量、告警收敛、告警升级等方面着手,减少告警发送的数量,提升告警准确性,最终提升解决问题的效率,降低问题恢复时长。下面我们从系统和功能层面说明如何降低告警量,把真正有价值的告警信息发送到用户手中。本文也将重点围绕告警消息收敛进行讲解。
从图1中可以看出各个监控系统中都有很多重复的功能模块,所以针对这些功能模块我们可以将其抽离出来,如图7所示将告警收敛、告警屏蔽、告警升级等能力统一建设在统一告警服务中。
这种架构下统一告警服务与检测相关服务完全解耦,在能力上具有一定的通用性。例如其它有告警或消息收敛需求的业务团队想接入统一告警,统一告警要能满足消息收敛发送的需求,同时也要满足消息直接发送的需求。统一告警会提供灵活可配置的消息发送方式,提供简单、多样的功能满足各类需求。
图7 统一告警系统结构图
告警收敛
对于告警平台每天会产生数以万计的告警,这些告警对于运维或开发人员都需要去分析、甄别优先级、并处理故障。数以万计的告警如果不加收敛每条异常都发送告警,势必会增大运维人员的工作压力,当然也不是所有的告警都需要并且有必要发送给运维人员进行处理。所以我们需要对告警通过多种手段进行收敛,下面我们从四个方面介绍一下如何进行告警收敛。
首次告警等待,当一个异常产生之后我们不会立即去做告警,而是通过等待一段时间才会去做告警发送,一般这个时间可以通过系统自定义,这个值如果太大就会影响告警延迟,太小不能提升告警合并效果。例如首次告警等待时间为5s,当一个服务下节点1出现A指标异常,5s内节点2也出现了A指标异常,那么发送告警时节点1和节点2会被合并到一起发送告警通知。
告警间隔,问题在没有恢复前,系统会根据告警间隔的配置每隔一段时间发送一条告警信息,告警间隔用来控制告警发送的频率。
异常收敛维度,异常收敛维度用来将同个维度下的异常合并在一起。例如同个节点路径A下,通过同一个检测规则产生的异常,会在告警发送的时候根据配置的异常收敛维度合并在一起。
消息合并维度,当多个异常收敛成一个问题,在发送告警的时候会涉及到消息合并,消息合并维度就是用来指定哪些维度可以合并。可能这样理解有些晦涩,我们可以通过图8看一下从异常到消息的转换过程。
假如一个异常有两个维度名字和性别,当这两个异常经过统一告警,我们会根据配置的收敛策略进行合并,从图中我们可以看到性别被定义为异常收敛维度,通常异常收敛维度的选择一定是两个或两个以上具有相同的属性的异常,这样在消息合并后只取相同属性的同一个值,对应到示例图,我们会将$sex占位符替换成男。
而名字是被定义为告警合并维度,就表示所有异常中名字是都要展示在消息文本中,所以在消息合并的时候我们会将$name占位符对应的信息一一拼接在消息文本中。
图8 消息文本替换示意图
告警认领
当出现告警后如果有人认领了该告警,那么后续相同告警只会发送给告警认领人。告警认领主要是为了解决告警有人跟进后,减少将告警发给其他人员,也能从一定程度上解决告警被重复处理的问题。被认领的告警可以取消认领。
告警屏蔽
对于同一个问题,可以设置告警屏蔽,后续如果有该问题对应的告警产生,那么将不会被发送出去。告警屏蔽能减少故障在定位解决过程中,或者服务在发版变更过程中造成的告警,能有效减少无效告警对运维人员造成的困扰,屏蔽可以设置为周期性的,也可以设置为屏蔽某一时段,当然也可以取消屏蔽。
告警回调
当告警规则配置了回调,那么当产生告警,就会调用回调接口,使服务或业务恢复正常。告警回调的目的是当某个服务有告警产生,希望系统能够通过一些自动化的配置,使服务恢复到正常状态,缩短故障恢复的时间,也能够紧急情况下第一时间快速恢复服务。
误告标注
对于一个问题,用户可以通过误告标注备注该异常是否为误告警。误告标注的主要目的是通过标注让系统开发人员知道异常检测过程中,哪些点还需要提升优化,提高告警的准确性,为用户提供真实有效的告警提供保障。
告警升级
当告警发生一定时间仍没有恢复,那么系统就会根据配置自动进行告警升级处理,然后将告警升级信息通过配置发送给对应的人员。告警升级一定程度上是为了缩短MTTA,当告警长时间未恢复,可以认为故障没有及时得到响应,这时就需要更高级别的人员介入处理。
如图9所示,每天告警系统会发送大量的告警,当然这些告警会分别发送给不同服务的告警接收人。告警并不是越多越好,而是应该第一时间准确反映出服务的异常情况,所以如何提升有效告警,提高告警准确性,减少告警量至关重要。通过以上系统设计和功能设计能够有效减少重复告警发送。
图9 主机监控告警次数图
— 5 —
上面我们从系统和功能层名讲解了如何针对老架构下存在的各种问题进行解决,那么对于这个构想我们应该用一套什么架构来实现。
下面我们看下如何设计这套架构。统一告警作为整个监控最后一环,既要满足告警发送能力也要满足业务服务发送通知的需求,所以统一告警的各种能力要具有通用性。
统一告警服务要做到与其它服务低耦合,尤其是与已有监控系统做到解偶,这样才能真正把通用能力释放出来。服务要能做到根据业务场景的不同适配不同的业务逻辑,比如有的业务需要做告警收敛,有的业务不需要,那么服务要提供灵活的接入方式以适用业务需要。
如图10所示,统一告警核心逻辑由收敛服务实现,收敛服务可以消费Kafka中的异常,也可以通过RestFul接口接收推送过来的异常,异常会先经过异常处理生成一个问题,然后将问题和异常存入MySQL库,经过告警收敛模块问题会被推送到Redis延时队列中,延时队列会用来控制消息出队时间,消息从队列取出之后会进行文本组装等操作,最后会通过配置发送出去。
图10 统一告警架构图
配置管理服务用来管理应用、事件、告警等配置信息,元数据同步服务用来从其它服务同步告警收敛所需的元数据。
— 6 —
统一告警的核心是告警收敛,收敛的目的就是减少发送重复的告警消息,避免因为大量的告警对于告警接收人造成告警麻痹。
前文已经说到使用延时队列做告警收敛,延时队列在电商和支付项目中使用较多,比如商品下单后10分钟未支付就要自动取消订单。在告警系统中使用延时队列主要目的是,在一定的时间内尽可能多的将同一个问题对应的异常合并在一起,减少告警发送的数量。
举个例,如果一个服务A有三个节点,当发生异常时,一般情况下每个节点的异常都会生成一条告警发送出去,但是经过告警收敛时候我们可以将三个节点的告警合并,由一条告警做通知。
延时队列有很多种方式实现,这里我们选择了Redis实现延时队列,选用Redis延时队列主要的原因就是其支持高性能的score排序,同时Redis的持久化特性,保证了消息的消费和存贮问题。
如图11所示,一个问题通过一系列校验去重之后放入Redis延时队列,队列中到期时间最小的问题会被排到最前面,同时有一个监听任务不断查看队列中是否有过期的任务,如果有过期的任务会被取出,取出的消息会经过消息组装等操作最终形成一条消息文本,然后根据配置通过不同的通道发送出去。
图11 延时任务执行原理图
— 7 —
基于统一告警服务定位来看,告警服务要能简单、高效、准确的告诉运维或者开发人员,哪里有故障需要去处理。所以对于后续服务的建设,应该考虑如何进一步减少人为的配置,增强告警智能化收敛的能力,同时还要增强根因定位的能力,以上通过AI的加持能够很好的解决此类问题。
目前各大厂商都在向着AIOps探索前进,并且已经有一些产品投入使用,但是AIOps何时大规模落地,就目前来看还需要一段时间。相较于AI的使用,当前最紧迫的就是让统一告警串联起上下游服务,从而打通数据,为数据流转铺平道路,增强服务的自动化程度,并且支持从更高维度实现告警发送,为故障的发现和解决提供更准确的信息。
如喜欢本文,请点击右上角,把文章分享到朋友圈
如有想了解学习的技术点,请留言给若飞安排分享
·END·
相关阅读:
小团队真的适合引入SpringCloud微服务吗?
DDD兴起的原因以及与微服务的关系
微服务之间的最佳调用方式
微服务架构设计总结实践
基于 Kubernetes 的微服务项目设计与实现
微服务架构-设计总结
为什么微服务一定要有网关?
主流微服务全链路监控系统之战
作者:Chen Ningning
来源:vivo互联网技术
版权申明:内容来源网络,仅供分享学习,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
我们都是架构师!
关注架构师(JiaGouX),添加“星标”
获取每天技术干货,一起成为牛逼架构师
技术群请加若飞:1321113940 进架构师群
投稿、合作、版权等邮箱:admin@137x.com