介绍

淘宝现在是一个由很多个应用集群组成的非常复杂的分布式系统。这些应用里面主要有处理用户请求的前端系统和有提供服务的后端系统等。这些应用之间一般有RPC调用和异步消息通讯两种手段,RPC 调用会产生一层调一层的嵌套,一个消息发布出来更会被多个应用消费,另外,应用还会访问分库分表的数据库、缓存、存储等后端,以及调用其他外部系统如支付、物流、机彩票等。
请试想一下,现在淘宝一个买家点击下单按钮所产生的网络请求到达淘宝服务器之后,就会触发淘宝内网数百次的网络调用。这些调用中有哪些出问题会影响这次交易,有哪些步骤会拖慢整个处理流程,双十一的交易高峰需要给应用集群分配多少台机器,这些都是需要考虑的。但是调用环境的复杂度,已经很难用人力去做准确的分析和评估了,这时候 EagleEye 就派上了用场。
EagleEye (鹰眼)通过收集和分析在不同的网络调用中间件上的日志埋点,可以得到同一次请求上的各个系统的调用链关系,有助于梳理应用的请求入口与服务的调用来源、依赖关系,同时,也对分析系统调用瓶颈、估算链路容量、快速定位异常有很大帮助。另外,业务方也可以在调用链上添加自己的业务埋点,使网络调用和实际业务内容得到关联。
异步场景:EagleEye基于ThreadLocal实现上下文的存储,所以当业务方使用同步的方式时对使用者透明,但是该方式无法支持异步线程的场景,所以在使用异步线程时需要手动传递上下文,当业务逻辑转移到异步线程时,需要先备份 EagleEye 的调用上下文到异步任务中,保证链路的正确性。
对异步场景的修改方案一(推荐)
提交异步线程前,需要做 EagleEye 上下文备份

Object ctx = EagleEye.getRpcContext(); // 从当前 ThreadLocal 备份
MyAsyncTask task = new MyAsyncTask();  // 这里的 MyAsyncTask 是一个业务自定义的 Runnable
task.setRpcContext(ctx); // 将 ctx 保存到 task 中
Future future = bizThreadPoolExecutor.submit(task); // 提交任务
// 后面继续执行其他逻辑,或者用 future.get() 等待任务的结果,都没有问题
// 如果 submit 多个 task,每个 task 都需要保存一份 ctx
真正执行任务时,还原 EagleEye 上下文
class MyAsyncTask implements Runnable {private Object ctx; // 用于存放之前保存的 EagleEye 上下文public void setRpcContext(Object ctx) { this.ctx = ctx; }public void run() {EagleEye.setRpcContext(ctx);  // 还原到 ThreadLocaltry {// 开始做异步逻辑,如调用 HSF、Notify、Tair 之类// ...} finally {EagleEye.clearRpcContext();  // 务必清理 ThreadLocal 的上下文,避免异步线程复用时出现上下文互串的问题}}
}

核心

TraceId

在复杂的分布式系统环境下,EagleEye是一个有广泛用途的调用分析和问题排查工具。与一般的调用信息埋点日志相比,EagleEye埋点的一个显著的不同点在于它的每条日志都有与每次请求关联的上下文ID,我们称为TraceId。通过TraceId,后期的日志处理时可以把一次前端请求在不同服务器记录的调用日志关联起来,重新组合成当时这个请求的调用链。因此,EagleEye不仅可以分析到应用之间的直接调用关系,还可以得到他们的间接调用关系、以及上下游的业务处理信息;对于调用链的底层系统,可以追溯到它的最上层请求来源以及中间经过的所有节点;对于调用链的上层入口,可以收集到它的整棵调用树,从而定位下游系统的处理瓶颈,当下游某个应用有异常发生时,能迅速定位到问题发生的位置。

rpcId

为了区别同一个调用链下多个网络调用的顺序和嵌套层次,EagleEye还需要传输和记录RpcId。
RpcId用0.X1.X2.X3…Xi来表示,Xi都是非负整数,根节点的RpcId固定从0开始,第一层网络调用的RpcId是0.X1,第二层的则为0.X1.X2,依次类推。例如,从根节点发出的调用的RpcId是0.1、0.2、0.3,RpcId是0.1的节点发出的RpcId则为0.1.1、0.1.2、0.1.3。
EagleEye 本身具备透明传输 TraceId、RpcId 的能力,这个能力通用可以用来传输业务的一些数据。例如,如果希望追加自己的业务信息到调用链上,应用可以通过 EagleEye 提供的 API 进行链路分组、链路打标等,EagleEye 会把这些信息一层层的透明往后端系统传递,而且信息也同样记录在每条调用日志里面。
EagleEye 数据透传的功能,在全链路压测、子帐号信息传递、二套环境项目隔离、强弱依赖检测、敏感操作的前端来源跟踪等场景都起到了不可缺少的重要作用。
用户数据(UserData)

EagleEye日志中的UserData字段为业务自定义的数据,该字段包含了RPC层的业务数据,该数据分为两种: 1.本地数据:记录在本地日志中; 2.链路数据:记录在本地日志中,并会跟随调用链传递至下游。
UserData是以"@“开头的字符串数据,可能包含多对业务数据,每对业务数据以KV格式记录,分隔符为不可见字符,两个KV之间的分隔符是0x12,K和V的分隔符是0x14,以K的格式区分本地数据还是链路数据,本地数据的K以”@"开头。 例子: K(本地)=,V=RPC; K(链路)=i,V=7325abff。其中|是EagleEye的日志字段分隔符,第一个@标识该字段为UserData,第二个@标识rpcName这个K是本地数据
|@@rpcName0x14RPC0x12i0x147325abff0x12
使用:
在业务代码中调用EagleEye-Core的API即可 本地数据:
EagleEye.attribute(“rpcName”, “RPC”);
链路数据:
EagleEye.putUserData(“i”, “7325abff”);

一般情况下,用户需要在客户端将TraceID、RpcID和UserData附在请求中,发送给服务端,服务端收到请求后将该信息放回EagleEye的上下文中。
客户端

RpcRequest createRpcRequest() {// 构造请求对象RpcRequest request = new RpcRequest();// 把 EagleEye 的当前上下文作为“附件”传送出去// 常见的 RPC 可以看看是否支持使用 header、attachment、attributes、properties 之类的手段传递request.addAttachment("EagleEye-TraceId", EagleEye.getTraceId());request.addAttachment("EagleEye-RpcId", EagleEye.getRpcId());request.addAttachment("EagleEye-UserData", EagleEye.exportUserData());return request;
}

服务端

// 从请求获取TraceId、RpcId、UserData,还原EagleEye调用链上下文
String traceId = request.getAttachment("EagleEye-TraceId");
String rpcId = request.getAttachment("EagleEye-RpcId");
String userData = request.getAttachment("EagleEye-UserData");
// 重新构建上下文
Map<String, String> context = new HashMap<String, String>();
context.put(EagleEye.TRACE_ID_KEY, traceId);
context.put(EagleEye.RPC_ID_KEY, rpcId);
context.put(EagleEye.USER_DATA_KEY, userData);
EagleEye.setRpcContext(ctx);

如何开启一次链路追踪:EagleEye.startTrace,这个方法会生成一个唯一的追踪标识,并将其存储在当前线程的上下文中,以便在当前线程中进行传递。同时,EagleEye.startTrace方法还会记录当前请求的开始时间,并将其存储在追踪上下文中,用于计算各个节点和服务的执行时间。
EagleEye.startTrace(traceId, traceName, 90); //标识一次trace调用的开始,traceName为用户设置,EagleEye在展示时会以该参数为分组条件(注意不要发散)
如果第一个参数为null,表示当前调用链没有父调用链,即当前调用链是根调用链,也就是整个调用链的起点。因为在分布式系统中,一个请求通常会经过多个进程和服务,每个服务都可能包含多个调用链,如果没有根调用链作为起点,那么就无法将这些调用链关联起来,从而无法准确地追踪和分析整个请求的调用链,影响了分布式系统的调试和性能分析。如果当前调用链有父调用链,则需要将第一个参数设置为父调用链的traceID,从而将当前调用链与父调用链关联起来,形成完整的调用链。

链路数据表

如下:
链路数据:
K 含义
i 入口标识符,最多8个十六进制字符
i2 口的别名标识符,最多8个十六进制字符(别名标识符)
s 链路签名,最多8个十六进制字符
r 入口签名,入口 IP 地址,在 TraceId 前缀不是 Java 入口 IP 的时候生成
t 线上全链路压测使用,值为 1 时表示这个链路是压测链路,使用了压测数据
tchain 线上全链路压测使用,记录压测的业务链路
u 在 tbsession 的埋点,由业务在前端传入的 UserId
w 前端染色埋点,由无线前端生成的ID
o 由业务在前端传入的用户子帐号信息
em 在 BUC Filter 的埋点,内部系统的操作员工号
ip 在 BUC Filter 的埋点,客户端IP
scm_project 二套环境项目标识,HSF、Notify 等都需要识别

链路追踪eagleEye介绍相关推荐

  1. PHP分布式链路追踪,SkyWalking:分布式架构链路追踪-SkyWalking介绍

    前面几篇文章提到了微服务相关系统的使用与搭建,在微服务架构下的问题也比较突出.正常系统下我们的每个请求都会在同一个系统中进行输出.但是在微服务架构中一个请求可能设置一到多个服务进行处理.服务之间相互依 ...

  2. go 链路追踪_Golang在七牛全链路追踪中的实践

    1.Go在七⽜牛全链路路追踪中的实践 刘凯 七⽜牛云⼤大数据团队(Pandora)架构师 2.⾃自我介绍 INTRODUCTION • 刘凯,七⽜牛,⼤大数据Pandora团队成员 • 2015年年, ...

  3. SkyWalking 微服务链路追踪

    目录 8. SkyWalking 微服务链路追踪 8.1 介绍 SkyWalking 8.2 Skywalking---服务搭建 8.3 SkyWalking---接入服务 8.3.1 windows ...

  4. 【全链路追踪】全链路追踪介绍

    什么是链路追踪? 链路追踪是一种针对分布式架构下实现请求链路可视化监控的一种技术. 它的核心目的就是去了解分布式系统中的请求调用行为,从而从整体到局部详细展示各项系统指标. 实现故障的快速定位,缩短故 ...

  5. 专为云原生、微服务架构而设计的链路追踪工具 【SkyWalking介绍及搭建】

    文章目录 前言. 当前企业级分布式微服务集群架构图 一. skywalking是什么 二. 为什么需要服务追踪 三 链路追踪框架对比 3.1 性能对比 四. 链路追踪的实际应用预览 4.1 捋清业务 ...

  6. 分布式链路追踪工具skywalking 介绍

    当企业应用进入分布式微服务时代,应用服务依赖会越来越多,skywalking可以很好的解决服务调用链路追踪的问题,而且基于java探针技术,基本对应用零侵入零耦合. skywalking是什么,有什么 ...

  7. SpringCloud链路追踪SkyWalking-第一章-介绍

    目录 参考 简介 链路追踪框架对比 cat zipkin pinpoint skywalking 性能对比 参考 SpringCloud组件链路追踪SkyWalking教学视频,微服务入门到实战教程 ...

  8. 一键托管,阿里云全链路追踪服务正式商用:成本仅自建1/5或更少

    随着互联网架构的扩张,分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务.消息收发.分布式数据库.分布式缓存.分布式对象存储.跨域调用,这些组件共同构成了繁杂的分布式网络. 在一次800 ...

  9. 服务追踪系统_一键托管,阿里云全链路追踪服务正式商用:成本仅自建1/5或更少...

    随着互联网架构的扩张,分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务.消息收发.分布式数据库.分布式缓存.分布式对象存储.跨域调用,这些组件共同构成了繁杂的分布式网络. 在一次800 ...

最新文章

  1. 前沿|《细胞》:绕过眼睛植入幻觉,科学家成功在盲人脑海中呈现指定图像!...
  2. 3.4.4 选择重传协议(SR)
  3. 融合了距离矢量和链路状态两种路由选择协议的优点
  4. 表单数据自动录入_「Excel技巧」Excel表格实时记录数据录入时间,关键还是自动哦...
  5. 计算机简单游戏有什么用,简单又好玩的互动游戏 简单又好玩的互动游戏有哪些...
  6. 1396: 队列问题(2)
  7. 阮一峰react demo代码研究的学习笔记 - demo8 debug - click triggers state change
  8. mysql left join 索引失效_MySQL索引列上做操作导致索引失效案例分析
  9. HAPPY_TOGETHER_WEEK15_ENJOY
  10. 成年人不懂这些道理,会吃很多亏
  11. 杭电1869六度分离
  12. [原创]项目管理知识体系指南之 13项目干系人管理思维导图
  13. 关于find指令的一点使用小心得 II
  14. spring中使用quartz(注解版)
  15. SCU4487 king's trouble I(深搜DFS)
  16. html5打开页面直接取纬度,html5获取不了经度和纬度
  17. 函数与反函数的图像性质
  18. 计算机键盘快速指南,MagicBook热键/功能键切换指南,快捷键介绍
  19. Linux嵌入式开发 -- imx6ull 主频配置
  20. js获取最近12个月的时间

热门文章

  1. Onethink上传服务器后登录不了的问题
  2. arcgis-api-for-js-之创建图层和添加图层(1)
  3. 夜深人静写算法(四十八)- 辛普森积分
  4. PX4开发指南中文版维护说明
  5. 线代学习笔记(一)——线性代数的通俗理解
  6. java程序连接2个数据库,Java连接数据库(2)
  7. MySQL学习笔记(总结)
  8. 一个三臂非劣效性检验的包简介——“ThreeArmedTrials”
  9. html特殊符号不显示,HTML特殊符号显示技巧
  10. 微信小程序 error 用户绑定的手机号需要验证,请在客户端完成短信