一、技术产生的背景

1.1 背景

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

说明:这里的 Pinpoint 并不是 pinpoint-apm,而是一篇论文

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

Modern Internet services are often implemented as complex, large-scale distributed systems. These applications are constructed from collections of software modules that may be developed by different teams, perhaps in different programming languages, and could span many thousands of machines across multiple physical facili- ties. Tools that aid in understanding system behavior and reasoning about performance issues are invaluable in such an environment.

from: https://research.google/pubs/pub36356/

大意是说现代互连网服务,通常都是用复杂的、大规模分布式集群来实现。这些应用构建在不同的模块上,这些软件模块,可能由不同的团队开发,可能使用不同的开发语言,可能部署在几千台服务器上,横跨多个数据中心。因此,需要一些可以理解这个复杂系统的行为,用于分析性能找出性能问题的工具。

1.2 一个请求的链路图示

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

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

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

这张图是由 5 台服务器提供相关的一个服务,它包含:A-前端,B,C-2个服务中间层,以及 2 个后端 D 和 E。

当一个用户发起一个请求,首先是到达前端 A, 然后发送 2 个 RPC 请求到服务器 B 和 C。B 马上会响应请求,但是 C 需要和

后端的 D 和 E 交互之后在返回给 A,最后由 A 来响应最初的请求。

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

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

二、Dapper 的分布式追踪

2.1 怎么定义图1链路信息

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

简单实现:为服务器每一次的发送和接收请求来收集追踪标识(message identifiers)和时间戳(timestamped events)。

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

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

黑盒方案:

假定需要追踪的除了上述信息之外没有额外的信息,这样使用统计回归技术来推断两者之间的关系。

基于标注方案:

依赖于应用程序或中间件明确地标记一个全局 ID,从而连接每一条记录与发起者的请求。

2种方案的比较:

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

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

Google的选择:

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

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

2.2 Dapper 数据结构模型

1、树形结构,追踪树

2、Span 以及 Annotation

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

  1. 图 2,是一个树形结构,每一个树节点是整个架构的基本单元,这个节点单元叫做 span,每个节点 span 都有一个唯一的 id:span id,还有一个 name:span name。

  2. 节点之间的关系可以用父子来表示,parent id 和 span id,parent id 就是它上一个 span 的 id;如果一个 span 没有父 id,那么它就是根节点,root span。

  3. 所有的 span 都有一个追踪请求 id,叫 trace id,作用是标识出一次完整请求。这个 trace id 是全局唯一。

  4. 最后,每个 span 还有一个 Annotations,记录每个 span 中的其他相关信息,比如 span 的开始时间戳,结束时间戳,发送信息等等信息,客户端和服务端信息都可以记录。

(图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. 对应用程序透明

对于应用程序来说,它根本觉察不到追踪系统的存在。

一个追踪系统,如果需要应用开发者主动配合植入追踪代码,那么追踪系统的存在不仅会导致众多额外代码的修改,最重要的是可能会使

运行良好的系统产生bug。

  1. 扩展性

google 在未来几年随着业务规模增长而扩展集群规模,追踪系统也能够应对这种情况。

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

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

Dapper 可以近乎零浸入的成本对应用程序链路进行追踪,得益于 google 的服务设施依赖几个少数的通用组件库,只要改造这

几个组件库就可以了。比如 google 中几乎所有进程间通信都是建立在 C++ 和 Java 开发的 RPC 框架上,那么我们只用改造这个 RPC 框架,追踪系统就能在依赖这个 RPC 框架的应用程序里生效。

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

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

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

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

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

  1. span 的数据写入(1)本地日志文件,
  2. 然后 dapper 的 daemon 进程和收集组件把追踪的数据从生产环境读取处理(2)。
  3. 最后一些(3)的 bigtable 仓库中。

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

引用参考

微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习的更多相关文章

  1. NET Core微服务之路:SkyWalking+SkyApm-dotnet分布式链路追踪系统的分享

    对于普通系统或者服务来说,一般通过打日志来进行埋点,然后再通过elk或splunk进行定位及分析问题,更有甚者直接远程服务器,直接操作查看日志,那么,随着业务越来越复杂,企业应用也进入了分布式服务化的 ...

  2. Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用

    一.分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(https://www. ...

  3. 基于zipkin分布式链路追踪系统预研第一篇

    本文为博主原创文章,未经博主允许不得转载. 分布式服务追踪系统起源于Google的论文“Dapper, a Large-Scale Distributed Systems Tracing Infras ...

  4. zipkin分布式链路追踪系统

    基于zipkin分布式链路追踪系统预研第一篇   分布式服务追踪系统起源于Google的论文“Dapper, a Large-Scale Distributed Systems Tracing Inf ...

  5. 分布式链路追踪系统Sleuth和ZipKin

    1.微服务下的链路追踪讲解和重要性 简介:讲解什么是分布式链路追踪系统,及使用好处 进行日志埋点,各微服务追踪. 2.SpringCloud的链路追踪组件Sleuth 1.官方文档 http://cl ...

  6. SkyWalking+SkyApm-dotnet分布式链路追踪系统

    SkyWalking+SkyApm-dotnet分布式链路追踪系统 对于普通系统或者服务来说,一般通过打日志来进行埋点,然后再通过elk或splunk进行定位及分析问题,更有甚者直接远程服务器,直接操 ...

  7. 使用Skywalking分布式链路追踪系统

    使用Skywalking分布式链路追踪系统 https://www.cnblogs.com/sunyuliang/p/11424848.html 当我们用很多服务时,各个服务间的调用关系是怎么样的?各 ...

  8. 微服务架构 | 10.3 使用 Zipkin 可视化日志追踪

    目录 前言 1. Zipkin 基础知识 1.1 Zipkin 链路监控的原理 2. 下载 Zipkin 服务器 2.1 下载 zipkin-server-2.12.9-exec.jar 包 2.2 ...

  9. go微服务框架Kratos笔记(六)链路追踪实战

    什么是链路追踪 借用阿里云链路追踪文档来解释 分布式链路追踪(Distributed Tracing),也叫 分布式链路跟踪,分布式跟踪,分布式追踪 等等,它为分布式应用的开发者提供了完整的调用链路还 ...

随机推荐

  1. thinkPHP ajax 状态修改(上架修改为下架)

    <td> {if $v.status==1} <span class="top{$v.id}" name="0" onclick=" ...

  2. NTFS权限详解

    NTFS权限是作为一个Windows管理员必备的知识,许多经验丰富的管理员都能够很熟悉地对文件.文件夹.注册表项等进行安全性的权限设置,包括完全控制.修改.只读等.而谈论NTFS权限这个话题也算是老生 ...

  3. Redis pub/sub

    list 类型, lpush + rpop 或 lpush + brpop 用作消息队列时,消息只能消费一次,且不支持多个消费者(消息只能消费一次),并且在客户端崩溃时容易丢失消息.而 pub/sub ...

  4. 企业网络防范Serv-U的漏洞

    很多企业都将自己的网站建立在互联网上,日常有专门的维护人员进行维护,很多时候对网站的更新当然不是直接在服务器上操作,而是将要更新的网页页面通过FTP工具上传到服务器上实现.因此必须要在服务器上搭建起一 ...

  5. Linux 安装mysql 看这一篇就够了

    mysql 安装教程 下载地址:https://downloads.mysql.com 查看系统中默认的mysql 依赖 rpm -qa | grep mysql rpm -qa | grep mar ...

  6. class文件和java文件区别

  7. Ajax的核心的对象是什么?

    Ajax的核心对象是XMLXMLHttpRequest 对象. XMLHttpRequest提供不重新加载页面的情况下更新网页,在页面加载后在客户端向服务器请求数据,在页面加载后在服务器端接受数据,在 ...

  8. Java 线程池中 submit() 和 execute()方法有什么区别?

    两个方法都可以向线程池提交任务,execute()方法的返回类型是 void,它定义在 Executor 接口中. 而 submit()方法可以返回持有计算结果的 Future 对象,它定义在 Exe ...

  9. springcloud断路器的作用?

    当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应) 断路器有完全打开状态:一段时间内 达到一定 ...

  10. phpstorm+xdebug调试详细教程

    对于PHP开发,初来咋到,开发环境的搭建和理解感觉是最烦人的一件事了.不像JAVA,打开一个Eclipse就可以开搞,Php的Debug都要几个插件来配合工作.这些都是死的,好说.但是对于Xdebug ...