Tracing 与 Metrics 的邂逅,提供更强大的 APM 能力

微服务监控领域,Tracing借助Metrics,可以在APM方面为开发运维人员提供更大帮助。本文采用Elastic APM和Grafana作为技术方案,分享借助Metrics对Tracing数据进行统计、分析与可视化,助力开发运维更高效

1. 微服务 Tracing Metrics

 1.1. 微服务监控三个领域 :Tracing Logging Metrics

在微服务领域,很早以来就形成了 Tracing Logging Metrics 相辅相成,合力支撑多维度、多形态的监控体系。

三类监控各有侧重:

²   Tracing :,它在单次请求的范围内,处理信息。 任何的数据、元数据信息都被绑定到系统中的单个事务上。 例如:一次调用远程服务的 RPC 执行过程;一次实际的 SQL 查询语句;一次 HTTP 请求的业务性 ID

²   Logging :它描述一些离散的(不连续的)事件。 例如:应用通过一个滚动的文件输出 debug error 信息,并通过日志收集系统,存储到 Elasticsearch 中; 审批明细信息通过 Kafka ,存储到数据库( BigTable )中; 又或者,特定请求的元数据信息,从服务请求中剥离出来,发送给一个异常收集服务,如 NewRelic

²   Metrics :特点是可累加的:他们具有原子性,每个都是一个逻辑计量单元,或者一个时间段内的柱状图。 例如:队列的当前深度可以被定义为一个计量单元,在写入或读取时被更新统计; 输入 HTTP 请求的数量可以被定义为一个计数器,用于简单累加; 请求的执行时间可以被定义为一个柱状图,在指定时间片上更新和统计汇总。

一直以来,三类监控技术各自围绕自己的关注点持续演进,产生了多种多样开源实现方案。

²   Tracing: Tracing 方面,已经从最开始的 Google Dapper 论文逐渐演进形成了 OpenTracing 规范,并有着众多的开源实现;

²   Metrics:CNCF 主推的 Prometheus 以及配套的 Grafana 已经逐渐盖过了 Zabbix 的风头,成为云原生时代炙手可热的监控利器;

²   Logging: 大的方向上 ELK 依然牢牢占据着日志采集与展示的龙头。

1.2.Tracing 技术速览

回到本文的主题, Tracing 相关技术从 Google 发表 Dapper 论文,到分布式、云原生技术的不断应用实践,已经逐步从单纯的服务跟踪发展到了业务监控、应用代码质量等多元化应用阶段。

2.    Tracing Metrics 可视化方案

Peter Bourgon 的《 Metrics,tracing, and logging 》博客中,给出了如下关系图。

通过上图,我们可以的清晰的发现,将 Tracing 信息通过 Metrics 进行聚合分析之后,可以实现服务请求级别的 Metrics 统计分析。

2.1. 示例工程

为了更加方便理解后续内容,我制作了一个简单的 Sample ,用于生成相关的 tracing 数据,以便于进行可视化分析。

一个 Spring Boot MVC 工程,提供了以下三个功能,每个功能里针对数据库有不同的访问次数,如下表:

序号

UI 页面

后台服务

数据库访问次数

1

首页

HelloController#index

1

2

登录

HelloController#login

50

3

登录后欢迎页

HelloController#hello

100

2.1.1.    首页

页面如下:

Controller 中代码如下:

@RequestMapping ( “/” )

public String index(){

     // 1 次数据库访问

userService .getAllUsers();

return “index” ;

}

2.1.2.    登录页面

页面如下:

Controller 中代码如下:

@RequestMapping (value = “/login” )

public String login(){

// 50 次数据库访问

for ( int i =0; i <50; i ++){

userService .create( “user” + i , i );

}

return “login” ;

}

2.1.3.    登录后欢迎页

页面如下:

Controller 中代码如下:

@RequestMapping (value = “/hello” )

public String hello(ModelMap map ){

// 100 次数据库访问

for ( int i =0; i <100; i ++){

userService .getAllUsers();

}

map .addAttribute( “host” , “http://sample.hello.com” );

return “hello” ;

}

2.2. 开源实现示例—— Elastic APM

ElasticAPM 包含四个组件:

²   APM agent: APM agent 是使用与服务相同的语言编写的开源库,可以像安装其他库一样将它们安装到服务中, agent 将检测服务的代码并在运行时收集性能数据和错误,这些数据缓冲一小段时间并发送到 APM server

²   APM server: APM Server 是用 Go 编写的开源应用程序,通常运行在专用服务器上,默认监听端口 8200 ,并通过 JSON HTTP API agent 接收数据,然后根据该数据创建文档并将其存储在 Elasticsearch 中。

²   Elasticsearch :Elasticsearch 是高可扩展的开源全文搜索和分析引擎,用于快速、近实时地存储、搜索和分析大量数据。此处用于存储 APM 性能指标并利用其聚合

²   Kibana: Kibana 是开源的分析和可视化平台,旨在与 Elasticsearch 协同工作,可以通过 Kibana 搜索、查看 Elasticsearch 中存储的数据,此处用于可视化 Elasticsearch 中存储的 APM 数据。

ElasticAPM 的架构图如下:

使用之前示例工程,按照 Elastic APM 的要求,搭建 ElasticSearch Kibana APM Server 之后,在应用启动时添加 APM agent 的代理,即可轻松与 ElasticAPM 进行对接,形成 Tracing 信息并进行分析。

2.2.1.    应用全部服务总体统计分析

按照应用维度,统计所有服务的整体情况,不区分具体服务。

2.2.1.1.        SPAN 分类耗时统计

收集到应用的所有 span 耗时分析:

2.2.1.2.        服务耗时时序分布图

应用所有服务的按照时间分布耗时分析,有平均值、 95% 99% 的耗时。

2.2.1.3.        服务请求数时序分布图

按照时间分布的应用所有服务请求数统计。

2.2.1.4.        服务执行时间排行

Elastic APM 中,每一个 Trace 定义为一个 Transaction ,可以轻松查看到每个服务总体的平均响应时间, 95% 的响应时间,每分钟请求数等。

点击每一个 Transaction ,可以查看每个服务的明细信息。

2.2.2.    具体单个服务维度执行明细统计

2.2.2.1.        SPAN 分类耗时统计

按照不同 SPAN 类型进行的耗时统计,可以看到对于数据库查询( h2 )的耗时占比 28.8%

2.2.2.2.        服务耗时时序分布图

按照时间分布的服务执行耗时统计,有平均值、 95% 99% 的耗时。

2.2.2.3.        服务请求数时序分布图

按照时间分布的服务请求数统计。

2.2.2.4.        服务耗时分布直方图

按照服务耗时统计生成的直方图,可以快速查看耗时的分布情况。

2.2.2.5.        Trace 信息抽样

可以查看具体服务的 Tracing 明细信息,具体到每个 SPAN 。对于数据库访问可以清晰的看到所指向的 SQL

2.3. 个性化定制实现方案—— ElasticSearch+Grafana

Grafana 作为在 Metrics 展示领域的后起之秀,已经越来越多的被采用。 Grafana 天然支持 Elasticsearch 作为 Metrics 数据源,这也大大方便了我们对 Tracing 做可视化初始。

我们直接使用 Elastic APM 生成在 ElasticSearch 中的 tracing 索引信息,即可在 Grafana 中灵活定制自己的统计图表。

2.3.1.    Elastic  APM 数据源

Kinbana 中,可以查看到 ElasticAPM 存储在 ElasticSearch 中的 index ,如下图所示。

对应的在 Grafana 中按照如下方式配置即可,分别为 Transaction Span 的数据源:

2.3.2.    个性化定制

配置完数据源之后,即可按照实际需要定制化统计分析页面,例如可以统计服务请求量、服务耗时排行等等。

以下是笔者自己定制的一个统计面板:

3.    借力 Metrics ,提供更好的 APM 服务

借助 Metrics ,可以轻松实现以下几类 APM 功能,并通过可视化工具进行展示:

²   服务性能分析:各个服务的响应时间统计;可视化展示最耗时服务排行榜;单个服务的平均响应时间、 90% 响应时间等;

²   代码质量分析:通过统计每一个服务调用 Trace 信息中 span 的数量,可以轻松获取到服务的复杂度排行。基于此可以分析是否有复杂的、不合理大量外部调用,尤其是在循环中访问数据库、外部服务等情况;

²   服务热度分析:基于 Tracing 信息中各个服务的调用频次,形成服务调用热力图,基于此可以对相应的弹性部署;

²   SQL 分析:在 Tracing 中,每一次 SQL 调用生成一个 SPAN ,基于此可以轻松的对 SQL 调用进行统计分析,从应用调用层面对形成慢 SQL 分析。

3.1. 服务性能分析

以下是示例工程中所提供的服务的性能统计,通过该统计可以快速发现应用系统中的慢服务,从而有针对性的进行调优。

建议: 在进行压力测试处于稳定阶段时,进行服务性能的分析会相对精确,否则偏差会比较大。

3.2. 代码质量分析

以下是示例工程中所提供的服务的调用深度排行,从这个排行表中可以快速发现服务实现逻辑的复杂度,有助有我们分析服务代码实现是否合理(例如:是否又在循环处理中大量调用数据库访问、其它中间件或外部服务)。

下图中,我们可以清晰的看到前两个服务分别有 102 52 Span ,点击查看可以发现分别调用了 100 次和 50 次数据库查询,查过了我们预设的深度阈值 20 ,显示为红色。

3.3. 服务热度分析

以下是示例工程中所提供的服务的请求次数排行,可以在 tracing 抽样统计上,帮我们分析应用各服务的热度。

3.4. SQL 分析

以下是示例工程中 SQL 执行时间的排行统计,基于该统计可以从应用调用数据库访问层面看到各类 SQL 的执行时间。再配合从数据库服务器监控的慢 SQL 统计,可以在很大程度上能够对应用的数据库访问合理性、数据库表设计合理性进行分析,从而排出数据库层面性能瓶颈。

4.    总结与展望

本文只是对 Tracing 使用 Metrics 进行可视化进行了初步的探讨, Tracing 还可以有更加广泛、复杂的应用场景,例如通过分析 Tracing 信息中的业务信息,可以实现业务监控。

在云原生和分布式使用越来越广泛的前景下,如何用好海量的日志、 Tracing 信息和 Metrics 信息,将会是一个非常具有挑战性而又很有前景的方向。