监控报警作为服务治理基础能力贯穿于稳定性建设的整个周期,但平台间领域割裂导致的能力无法协同、排障低效等问题一直是体系化建设的一大难题。严选基于故障处理驱动,通过监控+报警+事件总线机制的立体化协同建设探索,为微服务架构下的监控报警体系化能力演进提供更多可能。
1 前言
1.1 现状概述
自2017年底围绕“1-5-10”体系目标(如下图所示,部分置灰模块尚在规划建设中)开始着手搭建微服务架构下的监控、报警平台,历经4年+的建设,严选监控报警体系完整经历了从能力层建设->场景化定制->精准化完善->体系化融合的整个建设周期。
截止目前,已经接入严选99%以上的后端、前端、移动端以及非Java技术栈的应用/服务。涵盖从基础设施到服务性能到客户体验的全链路多层域指标监控;对外赋能包括稳定性平台、依赖分析平台、服务治理平台、压测平台、故障注入平台在内的十余个核心系统。形成了以三大监控系统为主、具备报警主动收敛、支持事件汇总、覆盖面相对完整的监控报警体系。
如上图所示:
APM平台:实现服务性能质量监控及链路追踪、业务监控基于日志实现业务核心指标监控;OpenFalcon(OF)完成资源层面监控。
锦衣卫报警平台:承接了监控体系中“不漏报”、“少误报”、“高响应”的报警需求。
事件中心:基于事件总线机制在稳定性保障领域的探索则为故障时间点的事件拟合、场景回溯提供了更多的可能。
受限于篇幅,后续将以连载的形式,分别阐述监控(全链路追踪)、报警、事件中心在严选业务场景下的建设历程以及过程中面临的问题及其对应的解决方案。本章作为“监控篇”将聚焦在以全链路追踪为核心的监控体系建设上。
1.2 监控体系本质
所谓监控,包含“监”+“控”,即应该具备对服务指标的运行情况进行感知、预判、以及应急处置的能力,是业务连续性保障能力的基础。从运维层面看来主要有以下几个方面:
了解服务状态
感知服务问题
预判服务风险
定位服务故障
衡量服务质量
为应急处置手段提供决策依据
1.3 监控体系标准
了解了监控本质之后,我们期待有一种科学的方式来管理和监控快速扩张、快速变化的基础设施及服务指标信息。那究竟什么样的监控才算完善?或者说成功的监控策略有没有衡量标准?
可以尝试从航空业的监控去降维看待这个问题:如果说线上运维的特点是如履薄冰,那航空业的运维则是事关生死。为了实现一架飞机的监控管理,飞机(波音777-200LR) 机身可以部署超过3000个传感器,内容覆盖飞机内部设备、人员操作、外部环境、燃油等多个维度的监控。鉴于监控报警的优先级不同,对监控的信息触达与处置方式进行分级,确保监控报警信息能够得到及时、有效处理。
基于上述经验,可以得出监控体系至少需要具备“快”,“准”,“全”的特点。实际上,大多数的监控平台也是这么做的,并因此衍生出了各种各样的监控手段,试图能够发现各种犄角旮旯的异常。但这样是否就高枕无忧?其实不然,这样带来的后果往往是“多”、“大”、“杂”,并且随着监控配置的腐化,每个运维、开发都得应对大量报警通知的狂轰乱炸,长此以往就会对报警麻木,大部分报警也不会处理,进而丧失监控的意义。而实际上的飞行监控也远不止依靠传感器采集分析数据进行报警而已,会依据采集的运行数据,基于数字孪生理论,构建一个数字孪生飞行模型,辅助地勤与飞行员进行决策。采用这种数字孪生技术监控飞机飞行,运营人员可以更好得分析和发现飞机运行的潜在风险,并触发异常报警,更快、更准地发现问题。综上,航空业的监控汇总起来有以下特点:
监控报警进行统一汇总,对监控报警进行分级管理。
提供多种不同类型的监控触达方式,促使报警及时得到有效处理。
分析采集的性能指标数据,为运行感知、辅助决策的提供数据支撑。
飞行监控系统与自动化系统相结合,为飞行决策提供支持。
映射到运维领域,一个成功的监控体系也至少需要满足以下特征:
1.3.1 统一的监控平台
监控体系建设过程中,为适应不同业务线的需求,往往衍生出不同的监控工具,每个工具都有特定目的并创建相对应的指标数据孤岛,这是一个缺乏一致标准和流程的环境。因此,常常无法在不同平台之间以清晰且标准的方式共享信息。此外,拥有不同的监控工具通常需要额外的成本和资源,并且通常只有少数人知道如何使用它们,这也就导致无法全面、统一地了解服务的运行状况和性能。
1.3.2 服务性能指标衡量
衡量服务性能的最主要手段之一就是测量系统中每个组件之间每次交互的延迟,高延迟就是“故障”。此外,系统用户体验质量还受到上下游服务性能的影响。如果要全面了解性能,就需要检查该服务中每个组件和服务间的延迟,所有这些延迟加起来决定了用户体验的成败,进而决定服务质量。想象一下,如果每100次的接口调用就有一次RT超时,服务质量会不会受到影响?如果每100个客户中就有5个客户出现页面卡顿,业务会不会受到影响?这就意味着,每个请求的每一次组件交互、每一次磁盘交互、每一次服务间调用、每一次的API查询都应该被纳入服务性能的衡量范围。
1.3.3 指标监控2.0 事件标准
传统的问题定位流程中,运维、开发人员往往需要在各个平台间跳转、在不同的数据流中确定问题的根源。这往往需要耗费数小时的时间。要解决这个问题,就需要有更多的上下文内容,带有上下文的指标数据,可以帮助问题关联事件,降低识别服务故障根因难度。
基于CloudEvent,我们提供一种统一的事件定义和描述规范,以提供跨服务、跨平台的交互能力。从而实现指标数据上下文的透传与关联。当所有的指标都能够以这种方式进行标记时,查询和分析能力将变得异常强大,并且能有效的支持故障时的事件拟合与场景回溯。
1.3.4 监控数据的二次挖掘
随着存储成本的降低,监控数据的价值得以被再次评估。基于历史数据监督学习的风险预判模型、基于故障管理的场景回溯等都进一步提高了历史监控数据的价值。历史数据的二次挖掘,往往可以带来有价值的学习,进而提升应对未来不可知问题的抗风险能力。
1.4 监控能力矩阵
基于上述监控目标及标准,我们抽象出了构建监控产品矩阵的整体思路:确保指标覆盖度、完善监控工具、丰富监控体系能力、并通过智能化探索持续优化监控手段,不断提升故障排查、定位、止损效率。
总结归纳起来就是,以监控、报警、事件丰富为核心能力,构建具备“监”、“管”、“控”手段的监控体系。
受限于篇幅,后文将以全链路监控作为监控平台的典型,结合报警收敛及事件总线机制,阐述严选在监控体系化上的建设历程。
2 全链路监控平台建设
之所以选取全链路监控平台的建设作为监控体系建设的缩影,是因为随着分布式架构、微服务的普及,一次请求往往需要横跨多个服务,这些服务可能使用不同的编程语言实现、部署在不同的服务器、横跨多个集群、访问不同的数据中心......单个用户请求会引发不同服务之间产生一连串顺序性的调用关系,链路的概念就此诞生。随着业务规模的增长,来自前端用户的请求频度会增加,链路也会变得更长。这也意味着服务间的调用关系变得越来越复杂。为了提升服务在复杂链路下的健壮性和稳定性,需要重点关注如何解决三个关键诉求:
如何梳理服务间的调用关系,并评估依赖上下游的合理性?
如何获取每一个服务性能指标,并对系统容量进行合理规划?
当系统出现故障时,如何快速发现问题、定位问题、快速止血?
解决以上三个问题的核心挑战,都来源于服务之间复杂的链路。这就需要有一套机制,对每一条链路的行为进行记录,并进行深入分析,提炼出有价值的数据信息。这个重要的机制,就是全链路监控。
2.1 从全链路特性看技术选型
业务链路的复杂度决定了全链路监控的特质:
低侵入性:监控系统应尽可能减少对业务服务的侵?,保持对使??透明,减少开发?员的负担,降低接?门槛和难度。
低性能影响:尽可能降低对业务服务造成的性能影响,?般来说,对CPU的耗?低于2%可以作为?个参考阈值。
灵活的接入策略:应该提供灵活的监控配置策略,让业务?决定是否接?,以及收集数据的范围和粒度。
时效性:实时有效的数据可视化功能,帮助相关?员感知服务状态,为性能评估、服务质量优化以及故障排查定位提供参考。
基于以上特性,对业界主流的三种开源监控系统进行了调研:
经过从架构和代码质量、应用侵入性、稳定性、性能、文档丰富性、社区活跃度、历经大规模线上考验的经历等方面综合考虑,最终选型Pinpoint。
2.2 从职责定位看平台架构
采集层
数据采集层负责从客户端采集原始监控数据,常见的采集方式有3种:
探针(agent):使用JavaAgent机制对应用的class进行字节码层面的增强,从而实现数据的采集。对应用无侵入,但会有一定的性能开销。
埋点(sdk):应用代码里硬编码加入一些“埋点”代码进行数据采集。采集数据比较有针对性,对应用侵入比较高。
日志(log):从日志文件采集数据。对应用无侵入,需要有规范、完善的日志输出。
分析层
实时读取、解析客户端上报的数据,按照业务指标的计算逻辑(如count、sum)统计分析,最终输出约定时间粒度(如1min)的指标值。计算特点就是要低延迟、高吞吐、计算稳定和准确。常见的计算模型有流式计算、实时计算,流式计算常见的技术有jstorm、galaxy、spark、Flink等。
存储层
存储海量监控指标数据。相比离线报表,实时的存储写入和查询效率面临更大挑战。常见的技术方案有hbase、 elasticsearch、mysql、tsdb等。
可视化层
实时读取监控指标数据,并图表化展示。页面展示需要考虑实时读取存储的延迟以及能满足业务方查看数据的各种对比需求(如同比、环比、不同方式累积等),同时要求支持不同业务数据的快速接入。
监控报警层
固定阈值的检测方法,缺点是不能适应数据本身规律性变化特性,也无法过滤历史数据中的异常和噪点干扰,同时也无法适应业务整体性能的抬升或下降。动态阈值报警,需要使用历史数据进行预测,自动识别异常。无论哪种方式,都需要重点关注如何实现“少误报”、“不漏报”。
2.3 从业务诉求看平台演进
从技术选型到今天,整个严选全链路监控平台的假设已持续了4年有余,根据目标、策略、资源约束等的差异,大概可以划分为4个阶段:
第一阶段(引入改造推广期):该阶段主要是引入Pinpoint补足严选监控系统的空白、适配严选已有基础设施、对Pinpoint的一些功能进行优化、改造和增强一部分Pinpoint不具备的功能,并在严选内部进行了推广使用。该阶段主要服务于服务端性能监控场景,不涉及移动端、前端、后端基础设施等。
第二阶段(全链路追踪完善期):该阶段对Pinpoint进行了大幅扩展,以Trace和Metric为核心,将性能监控延伸到了前端、移动端、后端基础设施(nginx/envoy/wzp),延伸到离用户最近、最贴近用户的地方,打造了完整的全链路大APM体系,覆盖了严选多端全链路性能监控,构建了端到端的监控体系。
第三阶段(全域精细化建设期):聚焦监控体系化协同建设,着力建设一个全方位立体化、精细化精准化、自动化智能化的监控体系。
第四阶段(体系化融合期):基于故障全生命周期管理,推动监控报警体系朝着数据标准化、逻辑自闭环、故障处理驱动的体系化目标演进。
2.3.1 引入改造推广阶段
该阶段的主要目标是填补能力空白,通过引入业界成熟APM方案,进行本地场景化的适配改造。
2.3.1.1 运维通道改造
解耦服务jvm启动参数与agent版本
Pinpoint官方版本的agent需要在应用/微服务的jvm启动参数里面添加以下三种参数:
参数较为冗余,极其容易配错,所以-Dpinpoint.agentId我们改造成了自动生成,-Dpinpoint.applicationName复用我们基建已有的-DappId。然而还有个最大的问题,jvm参数与Pinpoint agent版本耦合在一起,如果按这种方式部署,后期agent每次升级版本,所有的应用/微服务都需要修改jvm参数并重启应用。成千上万的服务器进行一次agent版本升级会带来巨大的成本与风险,会成为后续版本迭代最大的障碍。为解决这个问题,我们在jvm和pinpoint agent之间引入了一层路由层,路由层的逻辑很简单,就是基于严选ApolloY配置中心支持动态版本配置,支持agent在多版本之间进行路由切换。实现了agent的升级只需要修改对应apolloy上的版本配置即可。
2.3.1.2 存储能力增强
无论是Trace还是Metrics相关的数据,原生Pinpoint的存储均使用Hbase。Hbase对Metrics数据的存储存在如下缺点:
通过调研InfluxDB,OpenTSDB,Druid等时序数据库,Metrics指标数据存储方案选用基于InfluxDB的杭研NTSDB数据库。NTSDB相比Hbase具有如下优点:
最终我们通过引入NTSDB,对接口调入/调出、Top Sql、Dal等指标进行数据进行了统一存储。
2.3.1.3 拓展指标视图
2.3.1.4 统一可视化
2.3.2 全链路体系建设阶段
在前期弥补服务端监控能力空白的基础之上,这一阶段,我们将目标锚定为“以Trace和Metric为核心将我们的监控到拓展到全链路,覆盖移动端、前端、后端基础设施”。
2.3.2.1 数据抽象及建模
为了让Trace、Metric数据模型更好的适配移动端、前端、后端基础设施等场景,我们对Pinpoint原生的Trace、Metric数据模型做了进一步提炼,使其更加简洁、易于理解使用。传统Metric数据模型采用单一维度的key/value描述,无法支持复杂的筛选和聚合运算。以Metric2.0和时序数据模型为基础,构建多维度描述的tag和多个指标field的通用的Metric指标数据模型,使用NTSDB(InfluxDB)进行存储,支持丰富维度的实时聚合和筛选过滤。
2.3.2.2 全链路Trace追踪
在实际业务场景中,排查问题时常常会有这样的错觉:"明明后端服务响应很快,但是用户使用某个功能就是会感受到明显的延迟"。实际上,在用户触达和后端服务之间,除了隔着复杂的网络,还有各种基础设施(wzp/nginx/ianus),它们中间任何一环出现瓶颈都会直接影响性能体验。为了对这种场景下用户的体验进行透析,我们必须让我们的链路实现端到端的全链路追踪,将链路追踪延伸到前端,延伸到移动端,延伸到离用户最近的地方。
2.3.2.3 全链路指标监控
2.3.2.4 对外赋能
Caesar以能力地图和数据地图的形式对外赋能了多个外部系统,包括但不限于:
服务治理平台
稳定性平台
依赖分析平台
质量大盘
......
2.3.3 全域精细化建设阶段
经过前两个阶段的建设,监控平台的标准能力已经基本完备,该阶段的目标是在“全面”的基础上进行精细化、精准化建设:
精细化精准化监控视图
引入性能大盘、秒级监控大盘,数据源采用不受采样率影响的全量数据。
优化实例视图,接口与视图、SQL视图,解耦采样率,采用不受采样率影响的全量数据。
新增Error视图、Cache视图、依赖分析视图。
支持基于链路追踪和SQL追踪进行问题定位。
2.3.4 体系化融合阶段
随着监控能力的逐步完善、业务方的全面接入使用,过程中暴露出了一个显著的问题:监控服务功能松散,各个平台间的故障定位能力相互割裂、数据不共享,从故障处理视角出发需要有一个数据标准化、逻辑自闭环、故障处理驱动的统一的监控体系。
2.3.4.1 故障处理驱动下的监控体系
线上故障的处理原则是:“全面监控、快速反应、优先止损、及时修复、统一管理、分级处置”,监控作为最基础也最关键的一环。贯穿于整个故障处理流程。通过引入APM主动风险识别与在线诊断功能模块,完善故障生命周期中事前与事中阶段的处理手段。
2.3.4.2 故障处理驱动下的平台融合
体系化建设面临的问题:
能力割裂:各平台聚焦自身业务领域,能力建设各自为战。
跨平台能力缺失:平台间无法做到有效协同,故障排查定位效率低下。
服务间关系错综复杂:单一异常可能引发大面积的故障报警,导致核心报警被淹没,无法及时感知故障真实根因。
为解决以上问题,我们构建了基于故障处理的报警收敛机制,同时引入事件总线机制,结合CloudEvent事件标准,规范各平台间的数据流转标准,以事件中心为介质,承载各个平台的能力协同。也即后面将要详细阐述的故障处理驱动下的报警管理机制和稳定性保障域的事件总线探索。
3 小结
服务监控、追踪能力在微服务架构下的重要性不言而喻。而搭建一个服务监控平台,除了需要重点关注数据采集、传输、处理、展示这几个核心环节外,往往还需要根据实际业务特点拓展功能建设边界,比如基于实际业务需求的动态采样率控制、个性化组件支持、对接既有的基建平台、数据可视化体验优化等等。此外,一套合格的监控体系,绝对不是以孤立的平台形式对外提供服务,只有做到跨平台的数据融合、能力互补,才能真正开启监控“天眼”,为业务服务的连续性保驾护航。
综上,监控是一项非常复杂的事务,这种复杂度并不来源于监控流程本身,而是与业务的高耦合导致,监控体系需要跟随不断演变的服务一同演进。我们期望通过监控+报警+事件总线机制的协同建设更好地自适应这种演变,在后面的篇幅中也将详细阐述在体系化融合这个大目标下的报警管理机制和事件总线探索。
CIO之家 www.ciozj.com 公众号:imciow