在上一篇文章“分布式链路跟踪系统(一):Dapper 介绍”里讲了分布式链路跟踪系统的主要功能、实现原理,这一节讲一下基本的系统架构设计。分布式链路跟踪系统架构主要有三个部分:数据收集、分析处理、查询展示,如下图所示:

链路跟踪 ELK 链路跟踪框架_Trace

之前讲过 Trace 数据的埋点主要依赖通用的中间件,埋点记录的数据如何收集呢?有两种方式:Trace SDK 直接上报、写到日志文件再通过 Agent 收集上报。直接上报缺点是一旦出现网络抖动,上报失败,就会造成大量数据堆积在内存里,容易影响应用服务的性能。然而如果限制缓存的数据量,又可能因此而丢失数据。写到日志文件再通过 Agent 上报即可解决这个问题,这里的日志文件主要起到了缓存、持久化的作用,避免因为一时的网络故障而丢数据或影响业务。写到日志文件里,还能避免服务宕机后数据丢失。后者相比前者也有劣势的地方,多了磁盘读写,性能会稍差一些。

埋点数据收集到消息队列里,而非直接丢给流计算应用,也是让消息队列起到了一个缓冲、流量削峰的功能。消息队列一般都是分布式集群,数据保存多份,也可以避免出现故障时,数据丢失。消息队列一般使用 Kafka,其优点就是性能高、吞吐量大。

Trace 数据存储到消息队列后,就可以使用流计算(Storm、Flink 等)进行分析存储:

  1. 以全局唯一的 TraceID 为 RowKey 存储到 HBase里,方便根据 TraceID 查询链路数据。
  2. 多维度查询的 key/value 数据存储到 ElasticSearch 里,比如根据订单号查询 TraceID。
  3. 提取应用方法、链路拓扑等数据,存储到 MySQL 里,方便后续查询。
  4. 一些查询频次较高的元数据可以存储到 Redis 里,减轻 MySQL 的压力。

流计算可以说是实时在线分析,另外还会有离线任务对 Trace 数据做一些深度分析。

数据分析存储后,就可以提供给管理平台来查询和展示,一般管理平台除了提供前端页面给用户直接使用外,还会提供一些关键 API,比如链路详情查询、拓扑查询等,业务方可以利用 API 查询得到的数据和自身业务相结合进行分析。