目录
一、可见可观测
1.1 概述
可见可观测是服务治理反馈机制的第一步,只有获取到足够多有价值的数据,才能对服务的运行状态进行分析和控制。
1.2 服务可见性
1.2.1 概述
服务元数据平台负责维护服务相关的元数据信息,主要包括服务层面、接口层面、拓扑层面这几个维度的元数据信息,通过服务元数据平台,可以对系统提供全方位的可见性。
服务层面,服务元数据平台汇聚了当前所有的服务列表,默认按照服务功能进行分类,业务需要某种功能的服务时就可以直接到服务商城浏览和查询,做到服务信息的透明化,减少重复建设。为了增强服务查询的灵活性,可以支持多种服务查询方式,比如按照服务所属部门查询、按照服务属性查询等,服务基本信息平台化等。服务基本信息如下。
1.2.2 服务描述
简要描述服务提供的基本能力,服务的适用场景等,供潜在服务使用者参考,必要时可以加上服务的详细描述信息wiki,以及服务对应的邮件组和沟通群。
1.2.3 服务所有权
服务当前所属部门、服务当前的owner等。
1.2.4 服务对外接口
服务接口定义,使用说明和注意事项等。
1.2.5 服务SLA
服务对外的SLA承诺。
1.2.6 服务的上下游拓扑
服务商城中维护了每个服务的上下游依赖,基于上下游依赖,不仅可以查询上下游服务的使用方式和使用情况,同时也可以进行服务重大变更时的上下游服务通知。
1.2.7 服务变更
服务商城中维护服务每个重要变更的变更日志,重要变更时会通过相应机制知会上下游依赖,上下游会评估是否需要适配升级等,这样服务使用者可以从变更历史中了解到服务的整个发展脉络。
1.2.8 服务接入和资源配额管理
服务如何接入,资源配额如何申请等。
1.2.9 服务线上部署和线下测试环境信息
描述了服务线上和线下的部署信息,使用者直接基于平台给定的环境使用。
服务元数据平台的作用是将服务基本信息平台化,同时可以将服务接入、服务客服等日常工作从线下转移到线上,减少线下的人力成本开销。因此服务元数据平台的评价标准是微服务接入和运营时线下沟通的比重。
1.3 变更可见性
变更是引发系统故障的主要因素,通过对各个维度的变更进行系统的梳理和记录,不仅方便出现故障时的追溯和定位,后续还可以基于完善的变更事件库,对这些变更的原因、质量以及影响进行全面的审计和分析,从中找到规律性的东西,建立相应的改进反馈闭环。
服务变更是变更的最重要来源,常见的服务变更方式有应用变更、配置变更、数据变更以及预案变更等。
对于微服务架构来说,除了关注当前服务的变更之外,还需要关注上下游依赖服务的变更,以及部署层面关联服务的变更,比如和当前服务混部在同一台物理机上的其他服务变更。除了服务变更,还需要对服务周边的各个环境变更进行记录,比如网络变更、机器变更、机房变更、交换机变更,这些变更都可能对服务的正常运行产生影响。
1.4 可观测性
1.4.1 概述
微服务架构下,各个微服务采用分布式部署,并且通过网络进行分布式通信,随着微服务个数和集群规模的扩大,系统中会产生各种形式的故障,并且很多故障是无法事先预测的,因此需要有完善的平台和工具体系,能够对微服务的运行状态进行全方位多维度的监控,使得我们可以随时掌握微服务当前的运行状态,并且针对运行状态不正常的场景进行及时处理。
可观测性就是用于上述微服务状态监控的工具集合,具体分为Logging(日志系统)、Metrics(度量系统)和Tracing(分布式跟踪系统)3个层次,三者的关系图如下图所示:
1.4.2 Logging系统
日志用于对系统中离散的事件进行记录,比如服务的调试信息和错误信息,日志是系统监控的基石,也是服务状态监控和问题诊断的第一个抓手,通过日志可以大体判断系统的运行状态是否正常。
日志是最常见、最通用的监控手段,但服务的日志监控和告警一般都需要人工添加,不仅效率低,也很容易遗漏。同时不同服务的日志格式和日志信息可能都会有差异,不太方便进行标准化,不仅日志收集、处理和展示比较麻烦,有太多个性化的需求,而且每个服务的日志都不统一,基于日志的全系统问题定位也非常麻烦。
1.4.3 Metric系统
1.4.3.1 概述
为了提高日志和监控的标准化,引入了Metric的概念,Metric就是将日志中可以聚合的部分通过标准化的协议进行处理,Metric定义一套完善的日志收集、传输和处理标准,通过Metric可以实现日志和监控的标准化,同时基于Metric的日志聚合特性,聚合后的日志会小很多,减少日志系统的成本开销。
监控标准化是在业务中埋点主动上报标准业务指标来满足业务监控需求的解决方案。期望在业务完成标准上报之后,自动给业务提供调用关系拓扑、自动错误率监控、自动服务可用性计算、服务性能评估等高级功能。
1.4.3.2 日志监控系统的缺点
业务服务一般习惯于使用日志监控的方式,监控系统对日志的监控也容易实现,但日志监控有如下几个缺点。
1.4.3.2.1 规则简单
日志监控采集只能适用于简单规则,比如流量采集、接口平均耗时等,在耗时上采用平均耗时,在分析业务性能时缺少精细粒度的分位耗时信息,比较难科学反应模块性能。
1.4.3.2.2 业务量大时影响性能
日志监控分析在业务流量大的情况下,在线消耗性能比较多。
1.4.3.2.3 可维护性差
日志监控采用配置分析的模式,让监控系统和日志格式有依赖,如果修改代码的时候不小心调整了日志格式,忘记调整对应监控正则,会导致日志监控出错。
1.4.3.3 总结
相比之下,标准化监控,主动上报监控指标,可以自动绘出调用链,为服务可用性提供衡量指标,支持复杂的统计功能,可以定制业务相关的复杂策略。
为了实现监控标准化,针对监控项的收集和上报,需要制定一个规范,如果各个业务或者一个业务的各个接口都按照上述的规范,那么可以在监控自动化上做到更高程度,避免人工配置。
举个例子:如果一个业务的各个接口都有错误率,且各个接口的错误率不能超过30%,那么只需要配置错误率≥30%就报警,则新增一个接口自动添加报警,可以实现报警自动化。监控项规范可以规定,所有上报的监控项均需要关注QPS、耗时和错误率这几个服务基础监控指标。
标准化项采集实现起来也比较简单,可以借鉴开源系统statsd的设计思想,在业务代码中引入监控标准化SDK。SDK负责实现监控项埋点和统计功能,以及服务间RPC调用质量等业务指标,SDK通过UDP协议上报业务监控指标项到本机的Agent,本机Agent以一定的周期(如10s)为周期聚合业务指标,并将聚合结果发送到监控平台。
1.4.4 Tracing系统
1.4.4.1 概述
Tracing用于记录请求级别的信息,它会跟踪请求整个链路的执行过程和各阶段耗时信息,基于Tracing,可以定位请求性能问题和跨服务交互相关的问题。
1.4.4.2 分布式跟踪系统
1.4.4.2.1 分布式跟踪系统出现的业务背景
大型互联网公司的微服务架构下,一个业务可能会有上百个微服务组成,一次请求由几十次服务调用共同完成。这种架构下就会出现很多跨服务的问题,比如请求处理为什么突然变慢,问题具体出在那个环节;业务故障的排查,是哪个流程中出错等,通过分布式跟踪系统,可以建立一个以请求为中心的全局视图,查看请求处理过程中各个阶段的具体状态和处理情况。
1.4.4.2.2 分布式跟踪系统起源与发展
2010年,Google发表了一篇名为《Dapper,a Large-ScaleDistributed Systems Tracing Infrastructure》的论文,介绍了Google生产环境中大规模使用的分布式跟踪系统Dapper的设计原理和使用经验,Dapper掀开了分布式跟踪系统的序幕。之后Twitter根据这篇论文开发了自己的分布式跟踪系统Zipkin,并将其开源。现在不少国内外的大型互联网公司也都有自己的分布式跟踪系统,比如Uber的Jaeger、阿里的鹰眼、京东的Hydra、微博的Watchman等,这些分布式跟踪系统的原理基本都差不多,一般分为数据采集、数据传输、数据处理和数据展示4个方面,下面以Dapper为例,讲述分布式跟踪系统的大体实现。
1.4.4.2.3 分布式跟踪系统的原理
首先看下分布式跟踪相关的几个重要概念,TraceID用于对请求进行唯一标识,一般是请求进入链路处理入口时生成(比如在接入层生成),此后一直在请求处理的整个链路中一直携带和传递,不再修改。TraceID是分布式跟踪系统中最重要的概念,通过TraceID串联请求的各个阶段,同时也通过TraceID查询请求的整个处理链。
Span ID用于标识请求在一个模块内的处理过程,理论上讲,SpanID只需要做到同一个TraceID下唯一即可,不需要全局唯一。为了通过服务调用关系实现请求调用链信息的组织,调用下游服务时,需要将自身的Span ID和TraceID传递给下游服务,下游服务会将上游服务传递过来的Span ID作为自己的父Span ID,并通过一定的方式生成自身的Span ID,然后使用TraceID、父Span ID和Span ID生成标准化的Trace日志,分布式跟踪系统收集各个服务的Trace日志,然后通过TraceID完成一个请求对应Trace日志的收集,通过父Span ID和Span ID完成请求跟踪树的建立。
Annotation用于给跟踪信息添加相应的注释,这个注释信息是带时间戳的,Annotation可以添加任意请求相关的信息,通过Annotation,方便进行一些业务相关的问题定位。
对于分布式跟踪系统来说,TraceID和Span ID的正确生成是一个非常重要的前提,不同分布式跟踪系统的ID生成规则不一样,对于TraceID来说,必要条件是全局唯一,同时为了方便根据TraceID进行问题定位和追查,TraceID生成时可以加入一些请求相关的基本信息。
对于Span ID的生成,必要的约束条件是保证同一个请求下的不同节点对应的Span ID唯一即可。不同的分布式跟踪系统,生成Span ID的方式也不尽相同,比如阿里的鹰眼系统巧妙用Span ID来体现调用层次关系(例如0,0.1,0.2,0.1.1等),对于请求的根节点来说,使用一个特殊的标识来标识当前节点是根节点,没有上游信息。
1.4.4.2.4 分布式跟踪系统需要具备的优点
1.4.4.2.4.1 低侵入接入
低侵入接入不仅是分布式跟踪,也是所有服务治理相关特性的共同需求。服务治理特性接入最好能做到对业务透明,这样接入的过程中不会有特别大的阻力,如果业务需要花费比较大的改造成本才能完成接入,业务接入的意愿就不会那么强烈。
为了实现透明低侵入接入,一般可以将分布式跟踪特性下沉到服务框架或者Service Mesh层面,尤其是Service Mesh可以真正做到让分布式跟踪特性的修改对业务服务完全透明,业务服务零改动。
1.4.4.2.4.2 低开销
为了减少对业务服务正常运行的影响,分布式跟踪需要做到尽可能轻量,尤其是一些性能特别敏感的业务,需要随时调整Trace日志采集频率,甚至需要Trace日志采集开关。
为了减少对业务服务正常运行的影响,分布式跟踪需要做到尽可能轻量,尤其是一些性能特别敏感的业务,需要随时调整Trace日志采集频率,甚至需要Trace日志采集开关。
1.4.4.2.4.3 高稳定
分布式跟踪作为基础服务治理组件,如果没有足够的稳定性保障,会给业务服务带来非常严重的后果,因此分布式跟踪系统设计和实现过程中的各个环节都要考虑稳定性因素,尽可能简化设置。对于Trace日志输出来说,不要有太复杂的处理逻辑,同时日志收集代理尽可能轻量部署,减少不必要的依赖。
当前国内外主流互联网公司基本上都有自己的分布式跟踪系统,但这些系统实现各异,并且相互不兼容,无法实现跨业务、跨公司的全链路跟踪,制约了全链路跟踪的进一步发展,为了解决不同分布式跟踪系统API不兼容的问题,诞生了OpenTracing规范,OpenTracing是一个轻量级的标准化层,希望通过OpenTracing实现分布式跟踪的兼容互通和标准化。当前OpenTracing已进入CNCF,成为云原生基础设施的一部分,OpenTracing通过提供平台无关、语言无关的API,使得开发人员能够方便地替换追踪系统,目标是为全球的分布式追踪提供统一的概念和分布式跟踪标准。
OpenTracing数据模型中,重点定义了两个相关的概念Span Tag和Log Field,其中Span Tag定义一系列作用于整个Span过程的Tag;每个Span的log操作,都具有一个特定的时间戳(这个时间戳必须在Span的开始时间和结束时间之间),以及一个或多个field,Log Field定义了一系列标准化的Log Field字段,通过Span Tag和Log Field实现了分布式跟踪输出的标准化。
OpenTracing规范还在不断完善过程中,当前Jaeger和Zipkin均实现了对OpenTracing的支持。
1.4.5 总结
Logging、Metric和Tracing这3个系统关注的侧重点有所不同。Logging系统对服务的运行状态和事件进行记录,比如调试日志、错误日志等,日志记录一般会比较全(有时出于性能考虑可能需要在不同场景下打开相应的日志开关),这些日志会作为问题追查和定位的依据。Metric系统侧重事件聚合,相比日志来说,Metric关注的对象相对小一些,比如服务QPS、成功率、耗时等,聚焦核心指标,基于Metric可以方便实现服务核心指标的监控告警自动化。Tracing关注请求级别的处理。使用过程中一般先关注日志监控是否有问题,如果有问题通过Metric查看具体的服务和指标异常,最后通过Tracing进行全链路排查。
一般通过无处不在的Metric监控,发现大面上的异常或隐患,如机器cpu idle过低、服务崩溃退出等;再通过Tracing系统,查看异常机器或实例上的轨迹,确认异常由哪个环节引入,造成了多大损失(例如个别机器CPU idle低处理慢,因为有上游重试,未必会造成损失);如果问题由业务逻辑导致,此时基本能找到根因;否则再通过Metric系统,确定运行环境类根因,如查看异常机器或实例上的QPS、CPU idle率、进程CPU使用率的秒级曲线,最终判定cpuilde低是由QPS增加导致,还是其他进程CPU使用率增加导致。
一般来说,对于大故障,直接关联分析各种指标就能定位出问题;对于零星故障,业务逻辑故障,上下游耦合类故障(如调度),要通过跟踪才能分析清楚。
二、量化分析体系
2.1 概述
量化分析体系是基于数据对系统进行量化、定位和分析,然后产生相应的治理措施,指导接下来的线上治理和线下治理,接下来从度量、定位和风险分析这几个维度对量化分析体系进行展开讨论。
2.2 稳定性风险度量
稳定性工作包含的内容很多,在稳定性建设过程中,经常会遇到这样一个问题——服务当前的稳定性现状,不太好衡量和判断。比如,服务变更一直以来是影响服务稳定性的重要因素,由于没有明确的衡量标准和规范,很难说清楚服务变更做到什么程度才算是符合稳定性要求的变更,这样会导致执行服务变更的同学很难发现自己平常工作的不足,同时团队的管理者层面看不到自己团队变更风险的全貌和严重程度。服务变更只是稳定性建设的一个缩影,稳定性建设的很多维度和服务变更类似。
为了掌握稳定性建设的真实情况,同时引导和规范业务同学在稳定性建设时的做法,针对稳定性的一些重要环节,需要制订一定的度量标准,对业务同学日常的稳定性建设进行度量,明确告诉大家当前的稳定性工作处于什么水准,具体哪些地方需要改进。
以服务变更为例,流程规范规定高峰期不能上线,平台可以强制规定不能在这个时间上线,但一定会有紧急的需求需要在高峰期操作,所以平台还必须放开这个口子。这类操作带来的风险也是确确实实存在的,它不应该被经常执行;比如灰度检查通常暂停的时间越长越有可能发现问题,但平台只能约束至少有暂停或暂停一个固定时间,更长的暂停时间则由执行者把握。诸如这些问题,可以结合变更规范制定一个量化标准——更信用分标准。比如变更信用分标准可以规定,暂停时间越长分数越高,高峰期如有操作则需要扣分,同时不同优先级的模块采用不同的标准,最高优先级的模块有强制双重校验的要求,需要两个人校验后才能在平台上线,如果没有在平台执行这个要求也需要扣分。按照变更信用分标准,对每周的上线单进行系统分析,并按团队汇总、量化和排名,让大家能从全局的角度看到问题的总体情况和各自的严重程度,并能够从上往下索引到各个团队具体的变更单、变更人和变更参数,甚至直到具体的变更模块配置界面,以此促进各个团队有针对性地发现变更风险并清晰地知道如何进行完善。定期将每个团队本周的变更评分情况,以及存在变更风险的变更操作单,发送到对应团队的负责人与变更风险单的实际操作者,方便业务人员了解当前的变更风险,并及时针对性地进行改进。
针对稳定性建设的其他方面,我们也可以按照上述变更信用分的思路,建立相应的度量标准。比如监控告警,针对基础监控是否有遗漏配置、上下游依赖健康是否完备、告警策略是否符合要求等情况,可以推出监控健康分,量化服务监控告警的完备情况,引导用户进行监控告警的完善工作。比如预案建设方面,可以推出预案健康分,量化一个服务的预案建设情况,涉及降级限流等预案是否完备,预案执行是否符合灰度要求,预案是否可以回滚等。
对于稳定性度量来说,主要是确定具体的度量指标,以及每个度量指标的标准评分。其实具体评分并不是那么重要,关键是大家对度量标准能够达成一致,能够对稳定性日常工作有实际的量化指导效果。
2.3 基于多维度监控的故障定位
线上服务出现问题时,当有足够多的监控信息时,才能直观地定位问题。但随着业务规模变大,微服务的个数越来越多,链路、拓扑、网络越来越复杂,相应的监控事件越来越多。当出现故障,可能瞬间出现大量的报警信息,从众多告警中快速找到故障原因,确定相应的止损预案,是一个非常重要且有挑战性的事情。
出现故障时,首先需要确定故障的影响面,可以基于场景和分布式跟踪拓扑将业务组织成一个全局的“灭火图”,灭火图中包括所有核心服务的可用性指标,比如错误率、QPS、耗时等,出现故障时,先从灭火图中看出故障影响的业务和服务,接下来确定故障定位的范围。
为了从纷繁复杂的众多事件中定位具体的原因,可以将各维度的监控报警、各种变更事件以事件的方式,按照时间轴整合成一个时间线,有了事件时间线,我们就可以将关注焦点放到故障时间前一段时间内的监控告警事件以及变更事件上,从而根据具体的事件类型确定相应的预案和止损措施。
2.4 风险分析
基于线上实时的可观测数据,以及研发全流程的变更和操作数据,我们可以得出很多维度的报表和趋势数据。这些维度可以涵盖服务治理的各个环节,比如链路SLA、超时重试、容量管理、强弱依赖关系等,这些数据可以作为接下来分析的基础。
同时,根据之前的风险分析以及一些静态的服务元数据信息,会形成一个和当前实时治理数据对应的历史基准库,将当前数据和历史基准库进行比较,从中找到趋势和规律,进而发现潜在的风险。
实时治理数据分析后一些有价值的东西可以沉淀到历史基准库,作为后续风险分析的基础,进而形成一个风险分析的闭环机制。在基于风险分析的在线上治理和线下治理中,会结合具体的场景和实例进行全面的剖析。
好了,本次内容就分享到这,欢迎大家关注《微服务架构》专栏,后续会继续输出相关内容文章。如果有帮助到大家,欢迎大家点赞+关注+收藏,有疑问也欢迎大家评论留言!