分布式链路追踪框架的基本实现原理
目录分布式追踪什么是分布式追踪分布式系统分布式追踪分布式追踪有什么用呢Dapper分布式追踪系统的实现跟踪树和spanJaeger和OpenTracingOpenTracingJaeger结构OpenTracing数据模型Span格式TraceSpanOpenTracingAPI
本系列共有三篇:
。NETCore中的日志与分布式链路追踪
分布式链路追踪框架的基本实现原理(当前)
开源一个简单的兼容Jaeger的框架
柠檬(Lemon丶)大佬在一月份开业了柠檬研究院,研究院指导成员学习分布式和云原生技术,本月课题是分布式链路追踪,学习Dapper论文、Jaeger的使用,以及完成一个兼容Jaeger的链路追踪框架。
笔者将作业分为三部分,三篇文章加上实现代码,本文是第二篇。分布式追踪什么是分布式追踪分布式系统
当我们使用Google或者百度搜索时,查询服务会将关键字分发到多台查询服务器,每台服务器在自己的索引范围内进行搜索,搜索引擎可以在短时间内获得大量准确的搜索结果;同时,根据关键字,广告子系统会推送合适的相关广告,还会从竞价排名子系统获得网站权重。通常一个搜索可能需要成千上万台服务器参与,需要经过许多不同的系统提供服务。
多台计算机通过网络组成了一个庞大的系统,这个系统即是分布式系统。
在微服务或者云原生开发中,一般认为分布式系统是通过各种中间件服务网格连接的,这些中间件提供了共享资源、功能(API等)、文件等,使得整个网络可以当作一台计算机进行工作。分布式追踪
在分布式系统中,用户的一个请求会被分发到多个子系统中,被不同的服务处理,最后将结果返回给用户。用户发出请求和获得结果这段时间是一个请求周期。
当我们购物时,只需要一个很简单的过程:获取优惠劵下单付款等待收货
然而在后台系统中,每一个环节都需要经过多个子系统进行协作,并且有严格的流程。例如在下单时,需要检查是否有优惠卷、优惠劵能不能用于当前商品、当前订单是否符合使用优惠劵条件等。
下图是一个用户请求后,系统处理请求的流程。
【图片来源:鹰眼下的淘宝分布式调用跟踪系统介绍】
图中出现了很多箭头,这些箭头指向了下一步要流经的服务子系统,这些箭头组成了链路网络。
在一个复杂的分布式系统中,任何子系统出现性能不佳的情况,都会影响整个请求周期。根据上图,我们设想:
1。系统中有可能每天都在增加新服务或删除旧服务,也可能进行升级,当系统出现错误,我们如何定位问题?
2。当用户请求时,响应缓慢,怎么定位问题?
3。服务可能由不同的编程语言开发,1、2定位问题的方式,是否适合所有编程语言?分布式追踪有什么用呢
随着微服务和云原生开发的兴起,越来越多应用基于分布式进行开发,但是大型应用拆分为微服务后,服务之间的依赖和调用变得越来越复杂,这些服务是不同团队、使用不同语言开发的,部署在不同机器上,他们之间提供的接口可能不同(gRPC、Restfulapi等)。
为了维护这些服务,软件领域出现了Observability思想,在这个思想中,对微服务的维护分为三个部分:度量(Metrics):用于监控和报警;分布式追踪(Tracing):用于记录系统中所有的跟踪信息;日志(Logging):记录每个服务只能中离散的信息;
这三部分并不是独立开来的,例如Metrics可以监控Tracing、Logging服务是否正常运行。Tacing和Metrics服务在运行过程中会产生日志。
深入了解请戳爆你的屏幕
近年来,出现了APM系统,APM称为应用程序性能管理系统,可以进行软件性能监视和性能分析。APM是一种Metrics,但是现在有融合Tracing的趋势。
回归正题,分布式追踪系统(Tracing)有什么用呢?这里可以以Jaeger举例,它可以:分布式跟踪信息传递分布式事务监控服务依赖性分析展示跨进程调用链定位问题性能优化
Jaeger需要结合后端进行结果分析,jaeger有个JaegerUI,但是功能并不多,因此还需要依赖Metrics框架从结果呈现中可视化,以及自定义监控、告警规则,所以很自然Metrics可能会把Tracing的事情也做了。Dapper
Dapper是Google内部使用的分布式链路追踪系统,并没有开源,但是Google发布了一篇《Dapper,aLargeScaleDistributedSystemsTracingInfrastructure》论文,这篇论文讲述了分布式链路追踪的理论和Dapper的设计思想。
有很多链路追踪系统是基于Dapper论文的,例如淘宝的鹰眼、Twitter的Zipkin、Uber开源的Jaeger,分布式链路追踪标准OpenTracing等。
不能访问github。io的话,可以clone仓库去看
Dapper用户接口:
分布式追踪系统的实现
下图是一个由用户X请求发起的,穿过多个服务的分布式系统,A、B、C、D、E表示不同的子系统或处理过程。
在这个图中,A是前端,B、C是中间层、D、E是C的后端。这些子系统通过rpc协议连接,例如gRPC。
一个简单实用的分布式链路追踪系统的实现,就是对服务器上每一次请求以及响应收集跟踪标识符(messageidentifiers)和时间戳(timestampedevents)。
分布式服务的跟踪系统需要记录在一次特定的请求后系统中完成的所有工作的信息。用户请求可以是并行的,同一时间可能有大量的动作要处理,一个请求也会经过系统中的多个服务,系统中时时刻刻都在产生各种跟踪信息,必须将一个请求在不同服务中产生的追踪信息关联起来。
为了将所有记录条目与一个给定的发起者X关联上并记录所有信息,现在有两种解决方案,黑盒(blackbox)和基于标注(annotationbased)的监控方案。
黑盒方案:
假定需要跟踪的除了上述信息之外没有额外的信息,这样使用统计回归技术来推断两者之间的关系。
基于标注的方案:
依赖于应用程序或中间件明确地标记一个全局ID,从而连接每一条记录和发起者的请求。
优缺点:
虽然黑盒方案比标注方案更轻便,他们需要更多的数据,以获得足够的精度,因为他们依赖于统计推论。基于标注的方案最主要的缺点是,很明显,需要代码植入。在我们的生产环境中,因为所有的应用程序都使用相同的线程模型,控制流和RPC系统,我们发现,可以把代码植入限制在一个很小的通用组件库中,从而实现了监测系统的应用对开发人员是有效地透明。
Dapper基于标注的方案,接下来我们将介绍Dapper中的一些概念知识。跟踪树和span
从形式上看,Dapper跟踪模型使用的是树形结构,Span以及Annotation。
在前面的图片中,我们可以看到,整个请求网络是一个树形结构,用户请求是树的根节点。在Dapper的跟踪树结构中,树节点是整个架构的基本单元。
span称为跨度,一个节点在收到请求以及完成请求的过程是一个span,span记录了在这个过程中产生的各种信息。每个节点处理每个请求时都会生成一个独一无二的的spanid,当ACD时,多个连续的span会产生父子关系,那么一个span除了保存自己的spanid,也需要关联父、子spanid。生成spanid必须是高性能的,并且能够明确表示时间顺序,这点在后面介绍Jaeger时会介绍。
Annotation译为注释,在一个span中,可以为span添加更多的跟踪细节,这些额外的信息可以帮助我们监控系统的行为或者帮助调试问题。Annotation可以添加任意内容。
到此为止,简单介绍了一些分布式追踪以及Dapper的知识,但是这些不足以严谨的说明分布式追踪的知识和概念,建议读者有空时阅读Dapper论文。
要实现Dapper,还需要代码埋点、采样、跟踪收集等,这里就不再细谈了,后面会介绍到,读者也可以看看论文。Jaeger和OpenTracingOpenTracing
OpenTracing是与分布式系统无关的API和用于分布式跟踪的工具,它不仅提供了统一标准的API,还致力于各种工具,帮助开发者或服务提供者开发程序。
OpenTracing为标准API提供了接入SDK,支持这些语言:Go,JavaScript,Java,Python,Ruby,PHP,ObjectiveC,C,C。
当然,我们也可以自行根据通讯协议,自己封装SDK。
读者可以参考OpenTracing文档:https:opentracing。iodocs
接下来我们要一点点弄清楚OpenTracing中的一些概念和知识点。由于jaeger是OpenTracing最好的实现,因此后面讲Jaeger就是Opentracing,不需要将两者严格区分。Jaeger结构
首先是JAEGER部分,这部分是代码埋点等流程,在分布式系统中处理,当一个跟踪完成后,通过jaegeragent将数据推送到jaegercollector。jaegercollector负责处理四面八方推送来的跟踪信息,然后存储到后端,可以存储到ES、数据库等。JaegerUI可以将让用户在界面上看到这些被分析出来的跟踪信息。
OpenTracingAPI被封装成编程语言的SDK(jaegerclient),例如在C中是。dll,Java是。jar,应用程序代码通过调用API实现代码埋点。
jaegerAgent是一个监听在UDP端口上接收span数据的网络守护进程,它会将数据批量发送给collector。
OpenTracing数据模型
在OpenTracing中,跟踪信息被分为Trace、Span两个核心,它们按照一定的结构存储跟踪信息,所以它们是OpenTracing中数据模型的核心。
Trace是一次完整的跟踪,Trace由多个Span组成。下图是一个Trace示例,由8个Span组成。〔SpanA〕(therootspan)〔SpanB〕〔SpanC〕(SpanCisaChildOfSpanA)〔SpanD〕〔SpanE〕〔SpanF〕〔SpanG〕〔SpanH〕(SpanGFollowsFromSpanF)
Tracing:
aTracecanbethoughtofasadirectedacyclicgraph(DAG)ofSpans。
有点难翻译,大概意思是Trace是多个Span组成的有向非循环图。
在上面的示例中,一个Trace经过了8个服务,ACFG是有严格顺序的,但是从时间上来看,B、C是可以并行的。为了准确表示这些Span在时间上的关系,我们可以用下图表示:time〔SpanA〕〔SpanB〕〔SpanD〕〔SpanC〕〔SpanE〕〔SpanF〕〔SpanG〕〔SpanH〕
有个要注意的地方,并不是ACF表示A执行结束,然后C开始执行,而是A执行过程中,依赖C,而C依赖F。因此,当A依赖C的过程完成后,最终回到A继续执行。所以上图中A的跨度最大。Span格式
要深入学习,就必须先了解Span,请读者认真对照下面的图片和Json:
json地址:
后续将围绕这张图片和Json来举例讲述Span相关知识。Trace
一个简化的Trace如下:
注:不同编程语言的字段名称有所差异,gRPC和RestfulAPI的格式也有所差异。traceID:790e003e22209ca4,spans:〔。。。〕,processes:{。。。}
前面说到,在OpenTracing中,Trace是一个有向非循环图,那么Trace必定有且只有一个起点。
这个起点会创建一个Trace对象,这个对象一开始初始化了traceid和process,traceid是一个32个长度的字符串组成,它是一个时间戳,而process是起点进程所在主机的信息。
下面笔者来说一些一下traceid是怎么生成的。traceid是32个字符串组成,而实际上只使用了16个,因此,下面请以16个字符长度去理解这个过程。
首先获取当前时间戳,例如获得1611467737781059共16个数字,单位是微秒,表示时间2021012413:55:37,秒以下的单位这里就不给出了,明白表示时间就行。
在C中,将当前时间转为这种时间戳的代码:publicstaticlongToTimestamp(DateTimedateTime){DateTimedt1970newDateTime(1970,1,1,0,0,0,0);return(dateTime。Ticksdt1970。Ticks)10;}结果:1611467737781059
如果我们直接使用Guid生成或者string存储,都会消耗一些性能和内存,而使用long,刚刚好可以表示时间戳,还可以节约内存。
获得这个时间戳后,要传输到JaegerCollector,要转为byet数据,为什么要这样不太清楚,按照要求传输就是了。
将long转为一个byte数组:varbytesBitConverter。GetBytes(time);大小端if(BitConverter。IsLittleEndian){Array。Reverse(bytes);}
long占8个字节,每个byte值如下:0x000x050xb90x9f0x120x130xd30x43
然后传输到JaegerCollector中,那么获得的是一串二进制,怎么表示为字符串的traceid?
可以先还原成long,然后将long输出为16进制的字符串:
转为字符串(这是C):Console。WriteLine(time。ToString(x016));
结果:0005b99f1213d343
Spanid也是这样转的,每个id因为与时间戳相关,所以在时间上是唯一的,生成的字符串也是唯一的。
这就是trace中的traceid了,而traceprocess是发起请求的机器的信息,用KeyValue的形式存储信息,其格式如下:{key:hostname,type:string,value:YourPC},{key:ip,type:string,value:172。6。6。6},{key:jaeger。version,type:string,value:CSharp0。4。2。0}
Ttace中的traceid和process这里说完了,接下来说trace的span。Span
Span由以下信息组成:Anoperationname:操作名称,必有;Astarttimestamp:开始时间戳,必有;Afinishtimestamp:结束时间戳,必有;SpanTags。:KeyValue形式表示请求的标签,可选;SpanLogs:KeyValue形式表示,记录简单的、结构化的日志,必须是字符串类型,可选;SpanContext:跨度上下文,在不同的span中传递,建立关系;Referencest:引用的其它Span;
span之间如果是父子关系,则可以使用SpanContext绑定这种关系。父子关系有ChildOf、FollowsFrom两种表示,ChildOf表示父Span在一定程度上依赖子Span,而FollowsFrom表示父Span完全不依赖其子Span的结果。
一个Span的简化信息如下(不用理会字段名称大小写):{traceID:790e003e22209ca4,spanID:4b73f8e8e77fe9dc,flags:1,operationName:printhello,references:〔〕,startTime:1611318628515966,duration:259,tags:〔{key:internal。span。format,type:string,value:proto}〕,logs:〔{timestamp:1611318628516206,fields:〔{key:event,type:string,value:WriteLine}〕}〕}OpenTracingAPI
在OpenTracingAPI中,有三个主要对象:TracerSpanSpanContext
Tracer可以创建Spans并了解如何跨流程边界对它们的元数据进行Inject(序列化)和Extract(反序列化)。它具有以下功能:开始一个新的SpanInject一个SpanContext到一个载体Extract一个SpanContext从载体
由起点进程创建一个Tracer,然后启动进程发起请求,每个动作产生一个Span,如果有父子关系,Tracer可以将它们关联起来。当请求完成后,Tracer将跟踪信息推送到JaegerCollector中。
详细请查阅文档:
SpanContext是在不同的Span中传递信息的,SpanContext包含了简单的Traceid、Spanid等信息。
我们继续以下图作为示例讲解。
A创建一个Tracer,然后创建一个Span,代表自己(A),再创建两个Span,分别代表B、C,然后通过SpanContext传递一些信息到B、C;B和C收到A的消息后,也创建一个Tracer,用来Tracer。extract(。。。);其中B没有后续,可以直接返回结果;而C的Tracer继续创建两个Span,往D、E传递SpanContext。
这个过程比较复杂,笔者讲不好,建议读者参与OpenTracing的官方文档。
详细的OpenTracingAPI,可以通过编程语言编写相应服务时,去学习各种API的使用。
如果本文对你有帮助,别忘记给我个3连,点赞,转发,评论,
咱们下期见!学习更多JAVA知识与技巧,关注与私信博主(666)
假如我是一滴水三年级作文450字我是这大自然中的一滴水,别看我只是一滴小小的水,水的作用对人类,可是很有用的呢,你看,大自然中,有多么多的地方需要我啊:大海中,有我,千万滴水,让大海变得多么宽广;小溪中,有我……
国家海洋博物馆栈桥区明起对外开放来源:【津滨海客户端】津滨海讯(记者王梓)为庆祝六一儿童节,国家海洋博物馆栈桥区将于2022年6月1日起对外开放。据悉,国家海洋博物馆栈桥区免预约,游客需佩戴口罩,出示健……
北京青龙峡景区于6月2日起恢复开放尊敬的游客朋友:根据北京市最新疫情防控工作要求,北京青龙峡景区将于2022年6月2日起有序恢复开放,正常接待。景区严格落实限量、预约、错峰相关措施,单日游客接待量将……
如诗如画颐和园长廊沿线及其北侧景区之长廊分段景点介绍(二)(六)秋水亭秋水亭是长廊中的第三座观景亭。北与云松巢相对。秋水亭匾额与亭北檐匾额三秀分荣都是清漪园的旧物,为乾隆遗存。三秀分荣大意是奇花异草繁茂,分成祥瑞之象。三秀是指灵……
女排又一冠军名将大婚,现场群星闪耀,张常宁领衔七仙女亮相女排世联赛即将开打之际,前江苏冠军主帅蔡斌率领的中国女排,已经抵达了土耳其,6月1日首站对阵荷兰!此次中国女排大名单一共16人,其中国手大户江苏队贡献了2人,龚翔宇和刁琳宇!也……
河南附近旅游景区哪里好玩河南十大周边游玩景点推荐河南周边城市旅游去哪里玩好?河南周边游景点,有娲皇宫风景区、平遥古城、华山风景名胜区、西柏坡、汾河公园其中,娲皇宫,位于河北省邯郸市涉县中皇山上,为中国神话传说女娲娘娘炼石补天……
这个亚裔富豪真人秀越来越离谱了最近,聚焦洛杉矶亚裔富豪奢华生活的真人秀《璀璨帝国》第二季开播了。在去年的文章里,我们向大家介绍了亚裔富豪们的疯狂炫富行为。一年过去,他们在新一季真人秀里的表现,只能说是……
欧足联官方已委托一份独立报告,调查欧冠决赛相关事件直播吧5月31日讯本赛季的欧冠决赛前场外发生球迷骚乱,导致决赛推迟36分钟开赛。欧足联官方宣布,将委托葡萄牙议员对此事进行独立调查。本周一欧足联官网发布公告称,正式委托对……
杭州自驾1小时的好去处,现实版富春山居图藏不住了今年五一出省玩估计有难度,问了一圈身边的朋友找灵感,不少人都计划去富阳露营,说那边人少风景好而且玩法很丰富:逛景点、爬山、烧烤,是都市户外游乐的宝藏地没错了。在杭州这么多……
小贝次子和准二儿媳晒照!仿哥嫂造型差太远,富豪女不是谁都能比贝克汉姆家族真是热闹,不仅有三个儿子和一个女儿,还有老父亲,要说贝克汉姆和妻子维多利亚很恩爱,而贝克汉子的长子也和老婆妮可拉很恩爱,要说是贝克汉姆专情但其实好像并不是,因为贝克……
林宁2年帮老公王健林还债两千亿,嫁不嫁首富,我都是富豪林宁曾经说过这样的话:不管嫁不嫁首富,我都是富豪。林宁之所以会说这样的话,是因为她自身是真的有实力的。她曾在老公王健林陷入债务危机时,靠自身的能力帮王健林还债将近两千亿,这到底……
以诠释父爱为题目的作文父亲,是一个坚强的代名词,父爱更是坚强的表现,更是爱的表现。小时候,父亲是我熟悉的陌生人,现在父亲是我人生的引导者。是一直为我开辟前方,为我铺好未来的路的人。记得小时候,最喜换……
朝鲜城里人和农村人都喜欢的几道菜说到美食,我国好吃的东西很多,美食文化博大精深,分为八大菜系,每个菜系风味独特。外国游客到中国旅游,可以一饱口福,中国好吃的东西太多了。朝鲜和我国相邻,饮食文化也受到我国的影响……
幼儿园老师击打多名学生头部,被附近好心人曝光,处理结果出炉每个学生都是家长的心肝,特别是幼儿园的小同学们,更是家长捧在手心上的宝贝。磕到碰到也会心疼,可如果有人对学生击打头部,家长又会是怎样的心情呢?甘肃某幼儿园的一个老师,引起……
保育随笔中班幼儿园中班保育随笔保育员的随笔工作有助于保育员更加全面的审视自己工作的缺点,并且得出具体方法如何更好的对待幼童教育问题。下面就是品学网小编分享给大家的保育随笔中班,希望大家喜欢。保育随笔中班(一……
童年有趣,成年有酒回望历史,展望未来。随着六一的来临,我们离童年又少了些乐趣。如果辛苦,就用美食来解除。如果疲惫,就用美觉消消乏。如果烦恼,就用远足来开导。如果六一,就用些时间来回味童年。……
细节成就完美作文800字导语:每个成功者背后,都是细节在起决定性作用,完善小细节,才能做成大事,细节成就完美,小编整理关于细节成就完美的作文,欢迎阅读。第一篇:细节成就完美古人云:ldqu……
王心凌靠节目大翻红!穿卫衣套装嫩得像18岁,扎小辫子少女感爆最近《乘风破浪》第三季播出了,可谓是让王心凌再度爆火,本身就分为初代歌手的她可谓是很好展现出自己的优势,更是不少网友心里面的女神,更是有不少网友化身为王心凌男孩、王心凌女孩,单……
家乡的春节作文800字我们家乡的春节很独特,从腊月十九到来年的正月十五,人们都在快乐的忙活着,在忙活中享受着快乐。在腊月二十三之前,家家都要准备年货,包括我们这些小孩子也不例外。大人们买一些水……
炫界Pro美拍大赏,新的一天新的心动美拍时代,单品巧搭才是时髦精的摩登操作炫界Pro,型格在外带你一秒出大片色彩是时尚主张的表达炫界Pro缤纷多色5款纯色车身,4款双色车身……
39岁的王心凌,参加节目的角色本来是炮灰,没想到却刷屏了今年夏天无比的热闹,刘畊宏的女孩们,王心凌的男人们,偏偏孩子唱起了孤勇者,难怪有人调侃,希望寄托在下一代身上。39岁的王心凌,再次爆红的速度令人惊讶,即使是芒果台都没有想……
河南农村四大怪菜,个个都是当地人的心头爱,外地人看了摇头提起河南,你最先想起的是什么?一般人首先会想到那些有名的景点,比如古代皇室才能游玩的清明上河园,开封包公祠,洛阳的龙门石窟和白马寺,焦作的云台山。给我印象最深的是河南农村……
难忘的教师节优秀作文10篇感恩老师,并不需要我们去做什么惊天动地的大事,它表现在日常的点点滴滴:课堂上,一道坚定的目光,一个轻轻的点头,你在专心地听课,这便是感恩。以下是小编整理的难忘的教师节优秀作文,……
李盈莹独挑大梁!中国女排派四主攻出战国家联赛攻防两端肩负重任中国女排主攻手李盈莹北京时间5月25日,中国女排出征2022年国家联赛16人名单公布。这份名单最令人意外的是主攻线的人选。中国队仅派出4名主攻出战国家联赛,而且颇受期待的……