找回密码
 会员注册
查看: 34|回复: 0

天机阁——全链路跟踪系统设计与实现

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64454
发表于 2024-9-20 23:43:21 | 显示全部楼层 |阅读模式
小时光茶社传说中天机阁里有一台掌控世间一切的机器,万物运行由此产生。本文的“天机阁”是一个基于链路跟踪的监控系统,后台开发人员能够通过“天机阁”洞察“天机”,快速解决问题。摘要为了支撑日益增长的庞大业务量,业界大量使用微服务架构。服务按照不同的维度进行拆分,互联网应用构建在不同的软件模块集上,这些软件模块可能是由不同的团队开发、可能使用不同的编程语言来实现、可能布在了几千台服务器,横跨多个不同的数据中心,分布式系统变得日趋复杂。如何快速进行故障定位?如何准确进行容量评估?如何动态展示服务的链路?如何进行系统性能优化?这是分布式系统给后台开发同学带来的四大挑战。业界都是通过链路跟踪系统来解决以上问题,然而腾讯在链路跟踪方面比较欠缺。为了填补此空白,“天机阁”系统横空出世。“天机阁”通过采集、存储、分析分布式系统中的trace数据、指标数据和日志数据,完成全链路跟踪,从而解决上述问题。目前天机阁接入了1200+个服务,trace数据上报峰值500万/分钟,指标数据上报峰值1.3亿/分钟,日志数据每天30T。如此海量的数据天机阁是怎样处理的?天机阁的链路跟踪是怎样实现的?又是怎样做到低侵入,低开销的?这些问题本文将一一为您揭秘。背景 微服务崛起让系统越来越复杂如摘要所述,企鹅电竞也采用微服务架构。图1是企鹅电竞首页接口的依赖关系图,这张图大家可能看不清楚,看不清楚才是正常的,因为系统依赖的服务太多了。这种情况下一个请求涉及几十个服务,若其中某个关键服务出现了失败,只知道有异常,但具体的异常在哪个服务引起的就需要进入每一个服务里面看日志,这样的处理效率是非常低的。图1: 企鹅电竞首页接口拓扑图后台开发的痛微服务的好处不用多说,然而微服务也是一把双刃剑,其坏处就是系统太复杂,后台开发者面临着以下四大问题。1、故障定位难:一次请求往往需要涉及到多个服务,这些服务很可能是由多个团队负责的。一旦出问题,只知道有异常,但具体的异常在哪个服务引起的就需要进入每一个服务里面看日志,这样的处理效率是非常低的。最坏的情况可能要拉上多个团队一起定位。2、容量评估难:企鹅电竞每个月都就有好几场推广活动。活动形式还经常变化,导致流量入口经常不同。企鹅电竞有500多个模块,不同入口的流量导致各模块的qps增量是不同的,容量评估是一件难事。接入天机阁之前,企鹅电竞的每次大型上量活动都需要2个开发同学花一整天的时间来做容量评估,事倍功半。3、链路梳理难:一个新人加入后台团队,他在这个微服务体系中接手一个模块,根本不知道自己身在何处,不知道自己的系统被谁依赖了,也不知道自己的系统下游依赖哪些服务,需要看文档,一行行根据代码来分析,费时费力。4、性能分析难:一个服务依赖于后台多个服务,如果某接口的耗时突然增加,开发得从自己开始,逐步分析各依赖接口的耗时情况。业界解决方案 业界都是用分布式链路跟踪系统来解决上述问题。Dapper是谷歌生产环境下的分布式跟踪系统,算得上各大链路跟踪系统的鼻祖。2010年谷歌发表了Dapper的论文,之后各大互联网公司纷纷参照dapper的思想推出各自的链路跟踪系统。包括Twitter的Zipkin,韩国人的pinpoint,Apache的HTrace,阿里的鹰眼Tracing、京东的Hydra、新浪的Watchman等。我们的出路腾讯在链路跟踪这块比较薄弱,需要尽快填补这个空白。以上几款链路跟踪系统都各自满足了链路追踪的功能,但落实到我们自己的生产环境中时,这些Trace系统存在诸多问题。谷歌“dapper”和阿里“鹰眼”并不开源。Pinpoint和zipkin已经开源,然而pinpoint通过字节码注入的方式实现调用拦截和数据收集,仅能用于java服务器,Zipkin没有C++的版本,并且功能不够用。最终我们选择用zipkin的协议,参照阿里鹰眼的架构自建一套腾讯内通用的链路跟踪系统----天机阁。 天机阁介绍 天机阁是什么天机阁是一个以分布式链路跟踪为核心的监控系统。它通过采集、存储、分析分布式系统中的调用事件数据,再结合压测数据和TNM2数据,实现故障诊断、容量评估以及系统梳理等多种功能,大大降低开发人员的运维挑战,见图2。数据采集架构图见图11。图2:天机阁功能示意图注:“调用事件数据”包括“trace数据”、“指标数据”、“日志数据”三种。trace数据——指链路跟踪的span数据,主要用于链路跟踪、还原、绘制拓扑图。指标数据——指rpc的模调数据,包括分钟级别的rpc请求量、成功率、延时分布、错误码分布等等。日志数据——业务日志。 天机阁有些啥功能1.故障定位:天机阁利用跟踪数据,可以还原调用链,再结合日志数据,可以快速实现故障定位。例如:用户投诉他的视频点赞数不对,开发同学可以根据用户qq号码找到投诉用户的请求trace。查看trace详情就能很清楚的看到该请求在获取点赞结果的时候超时了,开发同学可以迅速完成定位并处理。Ui界面见图3。图3:trace跟踪ui界面2.链路梳理:有了跟踪数据,画出业务拓扑图就是水到渠成,图4是企鹅电竞某服务的拓扑图。图4:rpc调用生成树3.容量评估:天机阁的链路跟踪系统,能拿到各服务的调用拓扑图。指标数据统计模块能拿到rpc指标数据,tnm2系统能获得服务的部署信息,根据这些信息。压测系统能压测出各svr的性瓶颈。根据以上数据,天机阁能精确的评估出各服务的部署是否合理。若遇到大型活动,开发者只需提供入口接口的qps增量,天机阁就能预估出后续各依赖服务的qps增量,并给出推荐扩容数据。图5:容量评估结果4.性能分析:天机阁的压测系统能压测出单服务的性能数据,结合链路跟踪以及指标统计数据,能很好的分析出整个系统的性能瓶颈,找出优化方向。5.其他功能:除以上4个功能外,天机阁还有实时告警,过载保护,名字服务,指标数据查询等多个实用功能,欢迎大家到天机阁系统体验。体验地址:http://tjg.oa.com (天机阁担心数据被意外修改或者泄漏,权限没有全员开放,感兴趣的同学可以找alexzeng申请权限)。天机阁总体架构天机阁包含链路跟踪、压测系统、容量管理系统、名字服务四大系统,总体架构见图6。链路跟踪系统:链路跟踪是天机阁的核心,它负责采集、存储和分析rpc调用的trace数据、指标数据和日志数据,实现快速故障定位、链路梳理的功能,见图6的蓝色部分。压测系统:提供自动压测能力,目的是找出各服务的性能瓶颈,见图6左上角。容量管理系统:本系统结合trace数据、指标数据、压测数据和tnm2数据,实现精准的容量评估功能,见图6粉色部分。名字服务:这个就不多说了。图6:天机阁总体架构 链路跟踪的技术实现 链路跟踪的原理Rpc调用场景说明  首先来看一个简单的rpc调用链场景(见图7),一个请求通过接入层cgi调用下游的svr1,然后svr1先调用服务svr2,拿到结果后再调用svr3,最后组合svr2和svr3的结果,通过cgi返回给用户。这里发生了3次rpc,我们用①②③④⑤⑥表示了RPC的顺序,怎么做到跟踪还原呢?简单地说,天机阁利用rpc框架,在每次rpc的起点和终点进行数据上报。用Jstorm对上报的数据进行实时处理并存入hbase。管理端分析hbase数据进行可视化展示,以达到链路跟踪的目的。图7:简单的rpc调用场景 trace上报数据说明在天机阁跟踪树结构中,每个服务接口是一个节点,节点之间的连线就是span(跨度)。Span是链路跟踪系统中的主要数据结构,它记录了rpc主调节点和被调节点之间的关系。 Span包含数据如下:1.traceID:一次业务请求会分配一个唯一的TraceID, rpc的时候,框架会通过带内数据的方式吧TraceID传递到下游svr,本请求涉及的所有rpc上报的span拥有同一个唯一的2.TraceID, 系统可以通过TraceID把所有rpc的span关联起来,形成一个span集合。2.SpanID:span的ID,每个合并span在一个traceId下有唯一的SpanID。为了方便后续处理,一个rpc的“主调span”和“被调span”拥有相同的spanID,见图8相同颜色的span的spanID相同。3.parentID:父span的id,rpc调用有层级关系,所以span作为调用关系的存储结构,也有层级关系,就像图8所示,跟踪链是采用跟踪树的形式来展现的,树的根节点就是调用的顶点。所以,顶级span的parentId=0,拿图8所展现的例子来说,cgi请求svr1的span就是顶级span,spanID=1,parentid=0。 svr1请求svr2的span是顶级span的子span,spanID=2,parentid=1。而svr1请求svr3的也是定级span的子span,spanID=3,parent=1。很显然span2和span3是平级关系。这样就可以把rpc集合还原成调用树了。4.Event(事件):除了调用树,开发者还很关心rpc的时间关系以及耗时信息。为此,我们定义了4个rpc日志事件:a.client发送数据:clientsend简称csb.client收到回包:clientrecv简称crc.server收到数据:serverrecv简称srd.server发送回包:serversend简称ss“主调span”会包含cs和cr的时间点,“被调span”会上报sr和ss时间点。“合并span”拥有以上4个事件时间点。有了这些时间点,几乎所有阶段的耗时都可以计算出来。1.Name:接口名字,记录本次rpc调用是server的哪个接口。2.Result:调用结果,rpc的返回值,一般0标识成功。3.Caller:主调信息,包括主调svr名字,IP4.Callee:被调信息,包括被调svr名字,IP、port5.其他信息: span结构体中,还会存储一些方便分析问题的其他信息,但这些信息不影响链路跟踪,这里就不详述了。 trace上报过程说明说到这里,大家对span的印象可能还是有点模糊不清,于是我们继续拿图7的服务调用来举例,如果我们将图7的应用接入天机阁,将会看到图8的效果图8:span上报细节一个完整span既包含client数据,也包含server数据,所以一个完整span要分两次上报。rpc的起点上报的数据称为“主调span”,rpc的终点上报数据称为“被调span”,“主调span”和“被调span”也叫子span。子span在jstorm实时计算的时候,合并成“合并span”存储到hbase,上报过程见图8。图中一共3次rpc,共上报6个子span,这6个子span在计算层合并成3个合并span,详细过程如下:(前方高能预警,这个过程比较复杂,对上报过程不感兴趣的同学可以跳过)。a.第1个子span:cgi在发起rpc前,生成一个clientspan, traceId=111111, spanid=1, parented=0(没有父span)。并将这3个ID通过带内数据的方式传递给svr1。等cgi收到svr1的回包后,补全span的事件时间:cs=t1, cr=t12,并上报主调span。见图10中cgi上报的“主调span”。b.第2个子span:svr1从请求数据中解出clientspan,生成一个“被调span”,“被调span”的三个ID跟起点span一样,traceId=111111, spanid=1, parented=0。 Svr1发送回包给cgi后,就补全时间时间sr=t2, ss=t11,并上报“被调span”,见图10中svr1上报的“被调span”。c.第3个子span:svr1在发起svr2的rpc前,生成一个clientspan, traceId=111111, spanid=2(每个“主调span”生成一个新的spanid), parented=1(以本svr的“被调span”的id当parentId)。并将这3个ID通过带内数据的方式传递给svr2。等cgi收到svr2的回包后,补全span的事件时间:cs=t3, cr=t6,并上报“主调span”。见图10中svr1上报的spanid=2的“主调span”。d.第4个子span:svr2参照第2步,上报spanid=2的被调span。e.第5个子span:svr1参照第3步,上报spanid=3的主调span。f.第6个子span:svr3参照第4步,上报spanid=3的被调span。trace还原说明天机阁可以从hbase中查出所有spanid=111111的span。再通过spanid和praentID,可以还原调用树。还能计算各种耗时。例如:Cgi的请求总耗时 =span1.cr-span1.cs=t12-t1(注:span1指spanid=1的“合并span”)图中①的网络耗时 =span1.sr-span1.cs=t2–t1Svr1的调用svr2的耗时 =span2.cr-span2.cs=t6-t3Svr1的调用Svr3的耗时 =span3.cr-span3.cs=t10-t7时间差修正需要注意的是,span的时间戳精确到毫秒,各机器存在一定的时间误差。这个误差会导致耗时计算不太准确。天机阁通过以下办法,在展示结果的时候进行通过以下两步进行时间修正(参见图9)。1.保证每个span的cs,sr,ss,cr四个时间点是严格顺序的,也就是保证t1
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-27 14:55 , Processed in 0.805063 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表