热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:聊聊分布式链路追踪

本文由编程笔记#小编为大家整理,主要介绍了聊聊分布式链路追踪相关的知识,希望对你有一定的参考价值。原文链接:http://lidawn.github.io/2018/12/26
本文由编程笔记#小编为大家整理,主要介绍了聊聊分布式链路追踪相关的知识,希望对你有一定的参考价值。


原文链接:http://lidawn.github.io/2018/12/26/distribute-tracing/


起因

最近一直在做分布式链路追踪的调研和实践,整理一下其中的知识点。


什么是链路追踪

分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务、分布式数据库、分布式缓存等,使得后台服务构成了一种复杂的分布式网络。在服务能力提升的同时,复杂的网络结构也使问题定位更加困难。在一个请求在经过诸多服务过程中,出现了某一个调用失败的情况,查询具体的异常由哪一个服务引起的就变得十分抓狂,问题定位和处理效率是也会非常低。

分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。


Dapper

目前业界的链路追踪系统,如Twitter的Zipkin,Uber的Jaeger,阿里的鹰眼,美团的Mtrace等都基本被启发于google发表的Dapper。 Dapper阐述了分布式系统,特别是微服务架构中链路追踪的概念、数据表示、埋点、传递、收集、存储与展示等技术细节。


Trace、Span、Annotations

为了实现链路追踪,dapper提出了trace,span,annotation的概念。
Trace的含义比较直观,就是链路,指一个请求经过后端所有服务的路径,可以用下面树状的图形表示。每一条链路都用一个全局唯一的traceid来标识。

技术分享图片

Span之间存在着父子关系,上游的span是下游的父span,例如图中"frontend.request"会调用"backend.dosomething","backend.dosomething"便成为"frontend.request"的子span。

技术分享图片

链路中的rpc调用由span来表示,对应着树状图中的边,每个span由spanid和parentid来标识,spanid在一条链路中唯一。
下图是dapper论文中给出的一个"hepler.call"调用的span详解。
一个span一般由client和server两个部分的信息组成。按照时间顺序来解释,client节点(或者是调用方)首先发出请求,产生"client send"(cs)事件,紧接着server节点(或者是提供方)收到请求,产生"server receive"(sr)事件,server处理完成之后回复给client,产生"server send"事件,最后client收到回复,产生"client receive"事件。
Client与server两个节点的span信息合并成一次完整的调用,即一个完整的span。

技术分享图片

Dapper中还定义了annotation的概念,用于用户自定义事件,如图二中的"foo",用来辅助定位问题。
值得一提的是,zipkin中把cs,cr,ss,sr这几个事件称之为annotation,而对应dapper中的annotation在zipkin v1的数据模型中被称之为binaryAnnotation。


带内数据与带外数据

链路信息的还原依赖于两种数据,一种是各个节点产生的事件,如cs,ss,称之为带外数据,这些数据可以由节点独立生成,并且需要集中上报到存储端。
另一种数据是traceid,spanid,parentid,用来标识trace,span,以及span在一个trace中的位置。这些数据需要从链路的起点一直传递到终点,称之为带内数据。 通过带内数据的传递,可以将一个链路的所有过程串起来;通过带外数据,可以在存储端分析更多链路的细节。


采样

由于每一个请求就会生成一个链路,为了减少性能消耗,避免存储资源的浪费,dapper并不会上报所有的span数据,而是使用采样的方式。通过采集端自适应地调整采样率,控制span上报的数量,可以在发现性能瓶颈的同时,有效减少性能损耗。采样率的概念在其他的追踪系统中也被广泛使用。在zipkin小节中将更具体阐述zipkin的采样机制。


存储

链路中的span数据经过收集和上报后会集中存储在一个地方,Dapper使用了BigTable数据仓库,如下图所示,由于每种trace的span个数不尽相同,使得BigTable稀疏表格布局很适合这种场景,并且分散的span进行存储时按照traceid和spanid便可以插入到对应的行列中,使得收集程序可以无需做任何计算且无状态。同时链路的查询也十分方便,即取表中的一行。

技术分享图片


Zipkin

Zipkin是dapper的一种开源实现,也是业界做链路追踪系统的一个重要参考,其系统也可以即插即用。


架构

Zipkin的架构中包含Reporter,Transport,Colletor,Storage,API,UI几个部分。

技术分享图片

其中Reporter集成在每个服务的代码中,负责Span的生成,带内数据(traceid等)的传递,带外数据(span)的上报,采样控制。
Transport部分为带外数据上报的通道,zipkin支持http和kafka两种方式。
Colletor负责接收带外数据,并插入到集中存储中。
Storage为存储组件,适配底层的存储系统,zipkin提供默认的in-memory存储,并支持mysql,Cassandra,ElasticSearch存储系统。
API提供查询、分析和上报链路的接口。接口的定义见zipkin-api。
UI用于展示页面展示。

技术分享图片

Zipkin将Colletor/Storage/API/UI打包为jar包,可以直接下载运行。


数据模型

这里的数据模型为zipkin v2版本的数据模型。


Span

trace_id为16位或32位的hex字符串,idparent_id为16位hex字符串, 如果没有父span,parent_id为空。
kind标识服务节点的类型,有通信模型,cs和生产者消费者模型。
name为span的名字,如rpc调用的名字。
timestamp为span生成的时间戳,微秒。
duration为span的持续时间,client端,即为cr-ss的时间。
local_endpoint为本地节点信息,包含节点名称,ip与端口。
remote_endpoint为远端节点信息。
annotations为事件列表,每个事件用事件时间戳和名字表示。
tags为用户自定义的kv信息,如{"user-id":"lidawn"}。
debug表示是否为调试,该选项会无视采样概率,使所有span上报。
shared这个字段暂时没有太理解==。

message Span {
bytes trace_id = 1;
bytes parent_id = 2;
bytes id = 3;
enum Kind {
SPAN_KIND_UNSPECIFIED = 0;
CLIENT = 1;
SERVER = 2;
PRODUCER = 3;
COnSUMER= 4;
}
Kind kind = 4;
string name = 5;
fixed64 timestamp = 6;
uint64 duration = 7;
Endpoint local_endpoint = 8;
Endpoint remote_endpoint = 9;
repeated Annotation annotatiOns= 10;
map tags = 11;
bool debug = 12;
bool shared = 13;
}
message Endpoint {
string service_name = 1;
bytes ipv4 = 2;
bytes ipv6 = 3;
int32 port = 4;
}
message Annotation {
fixed64 timestamp = 1;
string value = 2;
}

带内数据与采样机制

Zipkin中对带内数据的传递有更加详细的描述。带内数据被称为b3-propagation,包含TraceId,SpanId,ParentSpanId,Sampled四个字段,每个server在生成span之后会得到TraceId,SpanId,ParentSpanId,穿递到下游server之后,下游server可以知道自己接下来要生成的span属于哪一条trace,并处在trace的哪一个位置。

由于带内数据涉及到进程之间通信,所以一般是由框架来做带内数据传递,这样可以减少代码的侵入性。如果服务之间使用http通信,则可以使用X-开头的自定义http head来传递带内数据。或者如grpc框架,使用clientContext机制在调用之间传递自定义的字段。目前开源的zipkin客户端一般只支持http和grpc两种方式。

Zipkin的采样字段Sampled有四种状态Defer/Deny/Accept/Debug,采样的一个重要前提是下游要尊重上游的采样决定,不能随意更改sampled字段。
Defer代表该span的采样状态还未决定,下游收到该状态时则可以对sampled字段重新赋值。
Deny代表该span不上报。
Accept代表span需要上报。
Debug一般用于开发环境,强制上报。

Root_span的sampled字段由系统的采样率来决定。如采样率为50%,则一半的带内数据中sampled字段为accept,其他为deny。


数据埋点及上报过程

根据zipkin的span定义,模拟一个简单的调用过程,分析数据埋点和上报过程。

技术分享图片



  1. server-1发起对server-2的调用,生成一个root_span, 生成trace_id,id,parent_id为空,并记录kind为CLIENT,name,timestamp,local_endpoint(server-1)信息,并将trace_id,id,parent_id,sampled信息传递给server-2。

  2. server-2收到server-1的请求,并收到trace_id,id,parent_id,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-2)信息。

  3. server-2发起对server-3的调用,生成一个新的span,该span为root_span的子span。 并记录kind为CLIENT,name,timestamp,local_endpoint(server-2)信息,并将trace_id,id,parent_id,sampled信息传递给server-3。

  4. server-3收到server-2的请求,并收到trace_id,id,parent_id,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-3)信息。

  5. server-3回复server-2的调用,记录duration,并上报span。

  6. server-2收到server-3的回复,记录duration,并上报span。

  7. server-2回复server-1的调用,记录duration,并上报span。

  8. server-1收到server-2的回复,记录duration,并上报span。

整个过程中上报4个临时的span,最终在zipkin中被合并和存储为两个span。


Open-Tracing

由于各种分布式追踪系统层出不穷,且有着相似的API语法,但各种语言的开发人员依然很难将他们各自的系统和特定的分布式追踪系统进行整合。在这种情况下,OpenTracing规范出现了。
OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。OpenTracing通过定义的API,可实现将监控数据记录到一个可插拔的tracer上。

Opentracing api的定义可以查看中文文档, 其并没有具体的实现。对于现有的系统,如zipkin适配opentracing,则需要额外基于现有的client编写适配代码。

以上。


参考



  1. Zipkin - https://zipkin.io

  2. Dapper - https://storage.googleapis.com/pub-tools-public-publication-data/pdf/36356.pdf

  3. Jaeger - https://www.jaegertracing.io/

  4. 鹰眼 - https://cn.aliyun.com/aliware/news/monitoringsolution

  5. Mtrace - https://tech.meituan.com/mt_mtrace.html

  6. Zipkin-b3-propagation - https://github.com/openzipkin/b3-propagation

  7. Zipkin-api - https://zipkin.io/zipkin-api/#/default/post_spans

  8. Zipkin-proto - https://github.com/openzipkin/zipkin-api/blob/master/zipkin.proto

  9. OpenTracing - https://opentracing.io

  10. OpenTracing中文 - https://wu-sheng.gitbooks.io/opentracing-io/content/

原文链接:http://lidawn.github.io/2018/12/26/distribute-tracing/


























推荐阅读
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了Flutter添加APP启动StoryView相关的知识,希望对你有一定的参考价值。 ... [详细]
  • windows平台使用NSP拦截具体进程的域名解析过程(xFsRedir的代理功能之域名代理)
    byfanxiushu2022-10-17转载或引用请注明原始作者。xFsRedir软件其中之一的功能就是实现了全方位的网络代理,从主机代理,到本地代理 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • [翻译]微服务设计模式5. 服务发现服务端服务发现
    服务之间需要互相调用,在单体架构中,服务之间的互相调用直接通过编程语言层面的方法调用就搞定了。在传统的分布式应用的部署中,服务地 ... [详细]
  • FIN7后门工具伪装成白帽工具进行传播
    fin7,后门,工具,伪装,成,白, ... [详细]
  • 后台自动化测试与持续部署实践
    后台自动化测试与持续部署实践https:mp.weixin.qq.comslqwGUCKZM0AvEw_xh-7BDA后台自动化测试与持续部署实践原创 腾讯程序员 腾讯技术工程 2 ... [详细]
  • SOA架构理解理解SOA架构,了解ESB概念,明白SOA与微服务的区别和联系,了解SOA与热门技术的结合与应用。1、面向服务的架构SOASOA(ServiceOrien ... [详细]
  • 前面刚有AWS开战MongoDB,双方“隔空互呛”,这厢又曝出2亿+简历信息泄露——MongoDB的这场开年似乎“充实”得过分了些。长期以来,作为“最受欢迎的NoSQL数据库”,M ... [详细]
author-avatar
纠结大王烨要人陪往_763
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有