2. 外婆都称赞的基于Jaeger的Span模型改造

前言

我们的目标是基于Jaeger来实现分布式链路追踪的Java客户端工具包,实际就是一个SpringbootStarter,在1. 看完这篇文章我奶奶都懂Opentracing了一文中我们详细的学习了一下Opentracing的相关概念以及阅读了相关的源码,同时特别重要的是我们还知道了Opentracing为我们造了很多轮子,这些轮子大部分时候都是可以直接用的,我们只需要指定具体的实现框架例如Jaeger和提供相应的扩展点例如Span装饰器,我们就能够造出来我们自己的轮子。

那么毫无疑问的,我们的分布式链路追踪的Java客户端工具包,会按照Opentracing规范并使用Jaeger作为具体实现来进行开发,但是这里存在一个问题,就是Jaeger中的Span模型,和我们直观的觉得一个服务就是一个Span的想法是不太一样的,具体怎么不一样,如何调整,且听下文详述。

Opentracingjaeger相关版本依赖如下。

opentracing-api版本:0.33.0
opentracing-spring-web版本:4.1.0
jaeger-client版本:1.8.1

正文

在1. 看完这篇文章我奶奶都懂Opentracing了一文中我们搭建了一个示例demo,这个示例大概表示了如下的一个请求路径。

大致就是从浏览器发起请求,请求先到client,然后经过RestTemplateTracingInterceptor拦截后,由RestTemplate发送到server,进server前,先通过了TracingFilter,最终才来到serverController。上述这个demo不太好演示本文的Span模型,我们做一下修改,修改后的请求路径如下。

结合上面的请求路径,再结合示例demoRestTemplateTracingInterceptorTracingFilter的实现,上图可以进一步做如下的Span模型抽象。

我们知道一个Span通常包含traceIdspanIdparentSpanId,所以我们按照示例demoRestTemplateTracingInterceptorTracingFilter的实现的规则,再把这些信息添加上,此时Span模型抽象如下。

到这里可以发现,上述每个Spanid是不一样的,即在接收到请求以及发起请求时均会生成一个新的Span,那么这里就存在一个情况,即Span代表的是一次请求接收或请求发起,这无疑是符合OpentracingSpan的定义的,但是这样其实是不太好理解的,可如果说一个Span就代表一次请求经过的某一个服务实例,那么是不是一下子就好理解了,就像下面这样。

这样的Span才是符合我们直观的认知的,同时Span记录的时间范围,就可以表示从这个实例接收请求到这个实例响应所花的时间,那么一次请求慢在哪个实例,通过看Span的时间就清楚了,所以我们需要对之前JaegerSpan模型做一下小小的改造,下面给出改造后的Span模型示意图。

上述模型,在每次作为客户端发起请求前,还是会创建一个新的Span,但是在作为服务端接收请求时,如果客户端跨进程传递了Span,则使用客户端传递过来的Span作为当前的Span,而不再新创建Span,这样一个过程,就好比是客户端(上游)替服务端(下游)创建好了Span然后给到了服务端(下游)一样。按照这样子改造,一个Span就可以表示一次请求经过的链路中的一个服务实例,而这,也正是契合ZipkinSpan模型。

现在既然已经明确了Span模型如何改造,那么具体到代码中,要怎么改造呢,Jaeger其实给我们留了口子,下面一起来看一下。

首先我们知道,无论是在服务端接收请求时创建Span还是在客户端发起请求时创建Span,均是通过JaegerTracer.SpanBuilderstart() 方法,简化版源码如下所示。

@Override
public JaegerSpan start() {
    JaegerSpanContext context;

    ......

    if (references.isEmpty() || !references.get(0).getSpanContext().hasTrace()) {
        context = createNewContext();
    } else {
        
        
        context = createChildContext();
    }

    ......

    JaegerSpan jaegerSpan = getObjectFactory().createSpan(
            JaegerTracer.this,
            operationName,
            context,
            startTimeMicroseconds,
            startTimeNanoTicks,
            computeDurationViaNanoTicks,
            tags,
            references);

    ......

    return jaegerSpan;
}

上述关键点在于会在JaegerTracer.SpanBuildercreateChildContext() 方法中创建父Span的子Span,这里的父Span有两种情况。

  1. 客户端跨进程传递过来的Span
  2. 当前线程中已经激活的Span

现在继续跟进JaegerTracer.SpanBuildercreateChildContext() 方法,如下所示。

private JaegerSpanContext createChildContext() {
    JaegerSpanContext preferredReference = preferredReference();

    
    
    if (isRpcServer()) {
        if (isSampled()) {
            metrics.tracesJoinedSampled.inc(1);
        } else {
            metrics.tracesJoinedNotSampled.inc(1);
        }

        
        if (zipkinSharedRpcSpan) {
            
            return preferredReference;
        }
    }

    return getObjectFactory().createSpanContext(
            preferredReference.getTraceIdHigh(),
            preferredReference.getTraceIdLow(),
            Utils.uniqueId(),
            preferredReference.getSpanId(),
            preferredReference.getFlags(),
            getBaggage(),
            null);
}

看到这里,就应该明白Jaeger给留的口子是什么了,即如果当前是作为服务端接收到请求要创建Span时,如果zipkinSharedRpcSpan配置为true,则不创建新的Span,而是直接使用客户端跨进程传递过来的Span,这完全就符合了我们上面的Span模型的改造思路。

那么最后一个问题,zipkinSharedRpcSpan怎么配置为true,其实就是在创建JaegerTracer时,调用一下JaegerTracer.BuilderwithZipkinSharedRpcSpan() 方法即可。

总结

Jaeger的默认实现逻辑中,一个Span通常代表一次请求接收或请求发起,如果我们想要让一个Span代表一次请求经过的链路中的某一个服务实例,则需要显式的指定JaegerSpan模型为ZipkinSpan模型,即在创建JaegerTracer时调用一下JaegerTracer.BuilderwithZipkinSharedRpcSpan() 方法即可。
原文:https://juejin.cn/post/7330331064370774054

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/602785.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度剖析Comate智能产品:科技巧思,实用至上

文章目录 Comate智能编码助手介绍Comate应用场景Comate语言与IDE支持 Comate安装步骤Comate智能编码使用体验代码推荐智能推荐生成单测注释解释注释生成智能问答 Comate实战演练总结 Comate智能编码助手介绍 市面上现在有很多智能代码助手,当时互联网头部大厂百度也…

2024年5月软考,别再傻傻啃书了!

备考2024年软考,不听课也不刷题,只是看教材的话,想要考试通过,几乎是不可能的,特别是基础比较薄弱的考生。 为什么只看教材通不过? 如果只是把教材从头到尾看一遍,毫无目的地看书,…

神经网络与深度学习--网络优化与正则化

文章目录 前言一、网络优化1.1网络结构多样性1.2高维变量的非凸优化1.鞍点2.平坦最小值3.局部最小解的等价性 1.3.改善方法 二、优化算法2.1小批量梯度下降法(Min-Batch)2.2批量大小选择2.3学习率调整1.学习率衰减(学习率退火)分段…

ogv转mp4怎么转?只需3个步骤~

OGV(Ogg Video)是一种开源的视频文件格式,起源于对数字媒体领域的开放标准的需求。作为Ogg多媒体容器的一部分,OGV的设计初衷是提供一种自由、高质量的视频编码方案,以满足多样化的应用需求。 支持打开MP4文件格式的软…

Windows+clion+protobuf+cmake实现protobuf的使用(被折磨了两天半)

针对protobuf源码和protoc的编译有很多博客写了,这里就不说了。但是很少看到在clion上配置的,因为这个要写cmake文件,本人是小白,学习了cmake之后才懂怎么搞。出现众多链接错误,这次展示一下有效的配置文件。(protobuf 3.21.6,当前最高版本是26.1我也不知道这个版本是怎…

XSKY SDS 6.4 重磅更新:NFS 性能飙升 3 倍,对象多站点等 10 多项功能强势升级

近日,XSKY星辰天合发布了 XSKY SDS V6.4 新版本,该版本在文件的性能提升、对象容灾能力完善方面改进异常显著,同时也大幅提高了存储系统的安全特性,适配更多的信创软硬件生态。 近来,软件定义存储(SDS&…

win11更新过后偶尔出现网卡详细信息为空

鼠标右键网卡属性,看下是不是多了一个Network LightWeight Filter 前面对号取消然后确定就能获取到IP了 详情请自行查看百度文库

细胞自动机与森林火灾与燃烧模拟

基于 元胞自动机-森林火灾模拟_vonneumann邻域-CSDN博客 进行略微修改,解决固定方向着火问题,用了一个meshv2数组记录下一状态,避免旧状态重叠数据失效。 参数调整 澳洲森林火灾蔓延数学建模,基于元胞自动机模拟多模式下火灾蔓延…

Saving Environment to FAT... Card did not respond to voltage select!

在移植uboot到全志H3时,出现了错误: Saving Environment to FAT… Card did not respond to voltage select! 判定与MMC有关。 同时还有报错: Error: ethernet1c30000 address not set. No ethernet found. 查看源码发现这与环境变量有关&am…

2024蓝桥杯CTF writeUP--爬虫协议

Dirsearch扫描网站 发现robots.txt文件 访问 直接去最后一个接口 到手

市场公关人的日常工作是什么?

作为一个从事多年的市场公关人,每到别人放假的时候就是我们最忙的时候,手上几个KOL项目安排探店,同时还要筹备品牌VIP活动。扎堆的事情每天忙得睁眼就是工作。 基本上来说,公关人是挺苦逼的,并没有大家看上去那么光鲜…

超级大转盘!(html+less+js)(结尾附代码)

超级大转盘!(结尾附代码) 网上看到有人用转盘抽奖,怀疑是不是有问题,为什么每次都中不了,能不能整个转盘自己想中啥中啥,查阅了网上写得好的文章,果然实现了只中谢谢参与&#xff0…

Unity如何使用adb工具安装APK

1、下载adb工具 SDK 平台工具版本说明 | Android Studio | Android Developers (google.cn) 2、配置环境变量 把platform-tools的路径添加进去就行 打开cmd,输入adb,即可查看版本信息 3、使用数据线连接设备,查看设备信息(…

【MySQL】事务及其隔离性/隔离级别

目录 一、事务的概念 1、事务的四种特性 2、事务的作用 3、存储引擎对事务的支持 4、事务的提交方式 二、事务的启动、回滚与提交 1、准备工作:调整MySQL的默认隔离级别为最低/创建测试表 2、事务的启动、回滚与提交 3、启动事务后未commit,但是…

快速搭建webase-front并且部署合约

PS: 因为我开发时候要用到fisco和webase-front,避免官方文档粘贴, 因此直接整理下面的笔记。开发的时候,好粘贴。1.搭建4节点联盟链 前提 curl 一种命令行工具 apt install -y openssl curl创建操作目录, 下载安装脚本 cd ~ && mkdir -p fisco && cd fisco…

Gartner发布应对动荡、复杂和模糊世界的威胁形势指南:当前需要应对的12种不稳定性、不确定性、复杂和模糊的安全威胁

当今世界是动荡(Volatile)、复杂(Complex)和模糊(Ambiguous)的,随着组织追求数字化转型以及犯罪分子不断发展技术,由此产生的安全威胁也是波动性、不确定性、复杂性和模糊性的&#…

《ElementUI 基础知识》el-tree 之“我的电脑”目录结构效果

前言 项目需求,Web 端获取服务器文件夹目录结构。目录数据是调接口获取,本篇略过,直接展现数据! 效果 实现 html 代码 8 - 15 行,自定义节点信息;代码 9 - 14 行,判断 icon 显示&#xff1b…

数据仓库项目---Day01

文章目录 框架的安装包数据仓库概念项目需求及架构设计项目需求分析项目框架技术选型系统数据流程设计框架版本选型集群资源规划设计 数据生成模块数据埋点主流埋点方式埋点数据上报时机 服务器和JDK准备搭建三台Linux虚拟机(VMWare)编写集群分发脚本xsyncSSH无密登录配置JDK准…

顶顶通呼叫中心中间件电话黑名单系统介绍

黑名单 有显示成功和失败导入数,可以禁用也可以启用,如果禁用状态就是不使用这一组黑名单,多个号码核验就是验证号码存不存在。黑名单只有管理员和操作员可以配置,租户是看不到黑名单的。但是黑名单跟租户是互通的。 可以单个号码…