一、技术产生的背景

1.1 背景

先来了解一下分布式链路追踪技术产生的背景。


在现在这个发达的互联网世界,互联网的规模越来越大,比如 google 的搜索,Netflix 的视频流直播,淘宝的购物等。

像这种大规模的应用,我们每点击一下鼠标,搜索一个关键字,背后可能会有几百台服务器上的N个服务来为我们提供服务。

我们用谷歌搜索:分布式 3 个字,搜索一些文章来学习分布式的知识。假如,查询时结果返回耗时 5 秒之多。

作为用户的你,等待这么长时间才返回结果,心里肯定不满意。

那作为一项服务来说,公司为了更好的服务用户,让用户满意,就必须要缩短用户等待返回查询结果的时间,要尽可能快的返回结果。

这样用户使用时才会感觉满意。


当然,这个优化任务就落在了产品技术研发人身上了。- -!

作为开发服务的产品技术人员,要怎么样做,才能让用户搜索时返回结果很快呢?


这时,产品研发人就思考在思考:

用户的一次搜索背后可能有几百个后端服务来提供服务。比如现在流行的微服务架构。

如果后端有一条服务比较慢,那么就可能会拖慢这整个搜索结果。

在这么多的服务中,要怎么样做,才能找出慢的服务呢?怎么找出是哪一条后端服务比较慢呢?

产品技术研发研究人员为了解决这个问题,慢慢想出了分布式链路追踪的技术,在到具体的技术实践,这是一个漫长的过程。

他们把研究成果汇聚在了 dapper 论文里。

当然它也借鉴了前人的研究成果 ,尤其是 MagpieX-Trace,还有 Pinpoint


在 [dapper](https://research.google/pubs/pub36356/) 论文开头有这样一段描述:

1.2 一个请求的链路图示

Dapper 论文里的一张图,表示一个请求可能经过的路径节点:

(图 1:这个路径由user用户的RequestX发起请求,穿过一个简单的服务系统。用字母标识的节点代表分布式系统中的不同处理过程,

来自:https://research.google/pubs/pub36356/)

上图的调用链经过了不同的系统,这个系统可能是不同团队维护,并且使用不同的语言开发。如果服务中出现了问题,比如请求异常,请求超时,那么怎么定位是哪个系统的哪一步出现了问题呢?

还有,对系统的监控是 7x24 小时不间断的。持续的对系统进行监控。

二、Dapper 的分布式追踪

2.1 怎么定义图1链路信息

对于上面图 1 的一个请求响应路径,怎么定义、怎么能实现分布式追踪呢?

从入口开始发起 Request 的请求者(图 1 中的 RequestX),与这个请求者相关的信息都要关联上,并记录下来分析链路关系,有什么好的方案呢?

2 种方案:黑盒(black-box)和基于标注(annotation-based)的监控方案。

黑盒方案:

基于标注方案:


2种方案的比较:

黑盒方案比标注方案跟轻便,但是它需要更多的数据,以获得足够的精度,因为他们依赖于统计推论。

标注方案最主要缺点,需要代码植入。


Google的选择:

在 google 的生产环境中,所有的应用程序都使用相同的线程模型,控制流和RPC系统,他们可以把代码植入限制在一个很小的通用组件库中,从而实现了监测系统的应用对开发人员是有效且透明。

dapper 的追踪架构是内嵌在 RPC 调用链的属性结构里。当然这个调用链路监控,还可以追踪其他行为,比如外界的 HTTP 请求,Gmail的 SMTP 会话和外部对 SQL 服务器查询等。

2.2 Dapper 数据结构模型

1、树形结构,追踪树

2、Span 以及 Annotation

(图 2:来自dapper论文:https://research.google/pubs/pub36356/)

(图3:表示一个单独的 span 结构信息图,来自 dapper 论文)

// 伪码表示结构
struct span {
    id        // 当前 span 的 id
    parent_id // 父 id,上一层 span id
    name      // 当前 span 的 name
    trace_id  // 标识一次完整请求的 trace_id
    Annotations []annotation // 表示 span 中的其它相关信息
}

struct annotation {
    star_time  // 此次 span 开始时间戳
    end_time   // 此次 span 结束时间戳
    client_send_info  // 客户端发送信息
    client_recv_info  // 客户端接收信息
    server_send_info  // 服务端发送信息
    .. ...
}

2.3 怎么把追踪代码值入相关程序中

dapper 里面叫植入点

怎么把相关追踪代码放入到程序中?并且能比较少的改动代码,又能达到下面三个设计目标。


dapper 里提了 3 个设计目标:
  1. 低损耗
  1. 对应用程序透明
  1. 扩展性

对于上面 3 点中最重要的一点就是追踪系统对**应用程序透明**。

那怎么做才能对应用程序透明?

当然 dapper 也允许应用开发人员给链路追踪系统添加额外的信息,以监控更高级别的系统行为,或帮助调试问题。它允许用户通过一个简单的 API 定义带时间戳的 Annotation。

2.4 采样率和追踪信息的收集

低损耗是 dapper 的一个设计目标,所以 dapper 对系统链路信息收集工作对基本组件性能损耗要尽可能的小。还有就是遇到大量请求时只记录其中一小部分。

(图4:dapper 收集管道总览,来自 dapper 论文)

dapper 追踪系统记录和收集信息过程分为三个阶段(如上图4):


看上面图4:一次追踪信息被存储为 bigtable 的一行,每一列相当于一个 span。

引用参考

== just do it ==
04-04 08:59