dubbo3+sleuth+brave实现链路追踪及traceId未传递或不对应的原因分析

本文讲述了作者在从SpringCloudAlibaba+dubbo2+nacos1.4升级到dubbo3+nacos2的过程中遇到的链路追踪问题,以及通过修改brave.dubbo.TracingFilter解决服务消费者和服务提供者间traceId和spanId传递的问题。

问题场景

笔者之前一直使用SpringCloud Alibaba + dubbo2 + nacos1.4进行开发,但是目前naocs2、dubbo3也已经推出有一段时间并逐渐达到生产环境可用状态,所以笔者也希望用最新版本的nacos2及dubbo3尝尝鲜。但在搭建框架的过程中遇到了链路追踪的问题,所以在这里详细记录一下。

SpringCloud Alibaba + dubbo2 + nacos1

笔者基于dubbo2和nacos1的框架的依赖版本如下(这里只展示链路追踪相关依赖):

SpringCloud Alibaba 2.2.5.RELEASE
Springboot 2.3.7.RELEASE
Dubbo 2.7.8 
Nacos 1.4.3
spring-cloud-starter-sleuth 3.0.0
brave-instrumentation-dubbo 5.13.7

基于dubbo2和nacos1,该依赖版本网上都有较为成熟的搭建方案。直接引入依赖,按照度娘上的配置一下yml文件,就能实现链路追踪,配置过程不太困难。这里就不详细介绍了。

SpringCloud Alibaba + dubbo3 + nacos2

在搭建基于dubbo3和nacos2的框架时也希望能实现链路追踪。其中方案一和方案二是目前Dubbo3官方手册列举的实现方案。
方案一:Skywalking
听说是最简单的,但因为要额外部署Skywalking,所以我暂未尝试这种方案。
方案二:OpenTelemetry或brave
我根据dubbo3的文档进行依赖的引入和yml文件的配置,但是发现服务提供者日志正常写入了traceId和spanId,但服务消费者无论traceId还是spanId都没写入,这个在dubbo的GitHub issue中也未有人提问,所以最终也没找到解决方案。
方案三:sleuth+brave
我尝试了沿用SpringCloud Alibaba + dubbo2 + nacos1框架时的sleuth+brave方案实现链路追踪,但我引入sleuth+brave并根据SpringCloud Alibaba + dubbo2 + nacos1框架时的yml文件配置后,发现虽然服务消费者和服务提供者的日志都写入了traceId和spanId但两个服务的traceId不一致,变成各写各的了,整个追踪链条并未正确串联起来。 最终通过查找GitHub上的issue终于找到一个brave的dubbo2扩展能兼容dubbo3的解决方案,在这里感谢@ShenFeng312这位大佬。
GitHub issue的comment链接如下:
https://github.com/apache/dubbo/issues/11650#issuecomment-1446313706

解决方案

笔者用的依赖版本如下:

SpringCloud Alibaba 2021.0.5.0
Springboot 2.7.8
Dubbo 3.2.4 
Nacos 2.2.0
spring-cloud-starter-sleuth 3.1.9
brave-instrumentation-dubbo 5.16.0

解决方案非常简单,只需修改一行源码即可。
修改brave.dubbo.TracingFilter#invoke中的RpcContext.getContext().getAttachments()改为invocation.getAttachments()
修改前:
在这里插入图片描述
修改后:
在这里插入图片描述
PS: 因为是要修改依赖的源码,所以各位读者可以复制该类、修改这行、增加Dubbo的SPI来指向自定义的TracingFilter。又或者自行重新打包jar。这里就不详细叙述了。

原因

根据GitHub上https://github.com/apache/dubbo/issues/11650#issuecomment-1446313706中@ShenFeng312大佬的分析,主要是因为dubbo2和dubbo3的RpcContext中invcation的attachment属性的实现方式改变了导致的。从issue的回复中其实也看到@ShenFeng312大佬也向brave提交了merge request,让brave-instrumentation-dubbo能兼容dubbo3,但是brave的开发人员一直未同意合并,这里就不展开说了,大家有兴趣可以自行去GitHub上看看。

疑问

根据知其然,也要知其所以然的想法,我尝试分析其中的原因,但也产生了一些疑问,以下疑问也会在后续的排查过程中逐一解答。

疑问一:dubbo2中为什么直接用RpcContext.getContext().getAttachments()就能传递traceId而不用invocation.getAttachments()呢?
疑问二:为什么dubbo3中brave.dubbo.TracingFilter继续用RpcContext.getContext().getAttachments()是不行的呢?
疑问三:dubbo3中的RpcContext.getContext().getAttachments()和invocation.getAttachments()有什么区别?

排查过程

追踪brave.dubbo.TracingFilter#invoke方法的try…catch…部分可以看到,最终传递到下一个服务的参数是通过invocation的,而traceId和spanId是保存在invocation的attachment这个map中的。所以我们接下来排查的目标都是检查并验证最终invoke时invocation的attachment中有没有traceId和spanId为准。
在这里插入图片描述

排查疑问一:

在这里插入图片描述
根据上述思路及brave.dubbo.TracingFilter#invoke方法中的注释得知,其实clientHandler.handleSendWithParent(clientRequest, invocationContext)一直都只是在操作RpcContext.getContext()的attachment并未操作invocation中的attachment
在这里插入图片描述
而invocation中的attachment其实是直到invoker.invoke(invocation)时才在org.apache.dubbo.rpc.protocol.AbstractInvoker#invoke方法把RpcContext.getContext()的attachment注入到invocation中的attachment中
在这里插入图片描述
所以通过上面的代码跟踪可以发现,dubbo2中虽然一直都是在操作RpcContext.getContext()的attachment,但会在AbstractInvoker#invoke方法中invoke下一个服务的前一刻把RpcCotext.getContext()的attachment注入到invocation中的attachment中,最终还是通过invocation中的attachment传递traceId给下一个服务的。
综上所述,在dubbo2中通过RpcContext.getContext().getAttachments()来操作RpcContext的attachment最终都会在AbstractInvoker#invoke方法里被注入到invocation中的attachment中,所以dubbo2中是可以通过RpcContext.getContext().getAttachments()来传递traceId的

排查疑问二、三:

追踪dubbo3中的RpcContext.getContext().getAttachments():
在这里插入图片描述
比对dubbo2中的RpcContext.getContext().getAttachments():
在这里插入图片描述
通过比较dubbo3和dubbo2的RpcContext.getContext().getAttachments()的实现,可以发现,dubbo3实现方式完全不同了,这个改动在dubbo3的官方手册中其实是有提及的
在这里插入图片描述
正是因为RpcContext.getContext().getAttachments()的实现改动,dubbo3中RpcContext.getContext().getAttachments()返回的不是RpcContext中的attachment也不是invocation中的attachment。而是把RpcContext中的SERVER_ATTACHMENT、CLIENT_ATTACHMENT复制一份并返回。后面再怎么put参数进RpcContext中的attachment都没有用了,即使后面在AbstractInvoker#invoke方法中把RpcContext中的attachment注入进invocation的attachment也没用了,因为put参数的时候是put进RpcContext的attachment的副本,而不是RpcContext中的attachment本身
而且! 本身dubbo3中AbstractInvoker#invoke方法中把RpcContext中的attachment注入invocation的attachment的实现也变了
在这里插入图片描述
不过这里已经不重要了,因为put参数的时候是put进RpcContext中的attachment的副本并未put进RpcContext的任何属性中。
综上所述,通过上述对源码的分析也解释了疑问二疑问三,解释了dubbo3中的RpcContext.getContext().getAttachments()和invocation.getAttachments()有什么区别和为什么dubbo3中brave.dubbo.TracingFilter继续用RpcContext.getContext().getAttachments()是不行的。

总结分析

总的来说,主要是dubbo3的RpcContext被拆分为四大模块才导致brave的dubbo扩展不能直接用,但是其实改动起来还是比较简单的。上述如果有说的不对的地方,还请各位大佬指正。下面笔者还画了一张图来帮助理解:
在这里插入图片描述
最后,版权归作者所有,任何形式转载请联系作者,谢谢!

内容概要:本文提出了一种面向通信优化的微电网分布式二次电压频率调控与功率均分方法,并通过Simulink平台进行了仿真实现。该方法针对孤岛微电网中多分布式电源的协同控制问题,采用分布式控制架构以减少对中央控制器的依赖,提升系统的可靠性与可扩展性。通过引入高效的通信机制与事件触发策略,在确保电压和频率快速精确恢复的同时,实现了各电源间有功与无功功率的均衡分配。文章详细阐述了控制算法的设计原理、稳定性分析过程以及关键参数的整定方法,并依托Simulink搭建完整的仿真模型,验证了所提方法在动态响应性能、抗干扰能力及通信资源利用率方面的优越性。; 适合人群:具备一定电力系统基础知识和仿真能力的研究生、科研人员及从事微电网、分布式能源系统相关工作的工程技术人员。; 使用场景及目标:①用于研究微电网中分布式电源的协调控制策略;②适用于需要实现电压频率恢复与负载功率均分的实际微电网系统设计;③为应对通信资源受限场景下的控制优化提供解决方案;④作为教学案例帮助理解分布式控制与二次调控机制。; 阅读建议:建议结合Simulink仿真模型同步学习,重点关注控制结构设计与参数整定部分,同时可延伸阅读文中提及的事件触发机制与弹性协同控制相关内容以加深理解。
内容概要:本文针对高比例清洁能源接入下的配电网重构问题,提出了一种融合需求响应机制的优化模型,并基于标准IEEE33节点系统进行仿真验证。研究通过引入需求响应策略,动态调节用户侧负荷,增强系统对风电、光伏等波动性可再生能源的消纳能力,同时结合网络拓扑重构以降低网损、改善电压分布,提升配电网运行的经济性与安全性。文中详细构建了计及辐射状约束、功率平衡与设备容量限制的混合整数非线性优化模型,采用智能优化算法求解开关操作序列与需求响应调度方案的协同最优解。通过Matlab编程实现仿真分析,验证了该方法在多重运行场景下的有效性与鲁棒性。; 适合人群:具备电力系统分析基础、熟悉Matlab编程工具,从事新能源并网、智能配电网优化、需求响应等领域研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于高渗透率分布式能源接入的配电网运行优化;②实现需求响应与网络重构的协同调度,提升系统灵活性与稳定性;③为智能配电网的规划、调度与决策支持提供技术参考与仿真平台。; 阅读建议:建议读者结合所提供的Matlab代码深入理解建模逻辑与算法实现流程,优先复现基础案例并逐步调整参数设置以探究同需求响应强度、新能源出力波动等情景下的优化效果,亦可进一步扩展至多时段动态重构、储能协同优化等更复杂场景的研究。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,旨在解决传统PID控制器在复杂动态水下环境中参数整定困难、适应性足的问题。文章首先建立了AUV的动力学模型并分析了其在水下扰动环境中的运动特性,进而提出一种将QLearning算法与PID控制相结合的自适应优化策略。该方法通过构建合理的状态空间、动作空间及奖励函数,使控制器能够依据实时控制误差和外部干扰自主调整PID参数,从而提升系统的响应速度、稳定性和抗干扰能力。研究在Matlab平台上进行了仿真实验,涵盖了稳态、恒定扰动和随机扰动等多种工况,结果表明所提出的QLearning-PID控制器在各项性能指标上均优于传统PID控制,验证了其有效性与鲁棒性。; 适合人群:具备自动控制理论、机器人建模与强化学习基础知识,从事水下机器人控制、智能控制算法开发及相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于提升AUV在复杂海洋环境下的轨迹跟踪精度与姿态控制性能;②为自适应控制策略与强化学习算法在实际工程系统中的深度融合提供技术参考与实现范例;③适用于智能控制器的设计、仿真验证、算法对比及优化研究。; 阅读建议:建议读者结合Matlab代码实现部分,深入理解QLearning与PID融合的程序逻辑,重点关注状态设计、奖励函数构造与参数更新机制,并可通过修改环境扰动控制目标进行拓展实验。
内容概要:本文围绕并网与离网模式下的风光互补制氢合成氨系统,开展容量配置与运行调度的联合优化分析,提出基于Python代码实现的双层优化模型。该模型充分考虑风能与太阳能出力的确定性,结合电解水制氢及合成氨工艺的能量转换特性,构建涵盖设备选型、容量规划与多时段运行调度的协同优化框架,旨在实现系统在经济性、能源自给率与运行可靠性之间的综合平衡。通过典型场景的仿真分析,验证了模型在同运行模式下的有效性,深入探讨了系统在离网与并网条件下的最优配置方案、调度策略差异及关键设备的运行特性,为可再生能源深度耦合化工生产过程的综合能源系统规划设计提供了重要的理论依据和技术支撑。; 适合人群:具备一定能源系统建模、优化算法及可再生能源技术基础,从事新能源、综合能源系统、氢能与绿色化工等领域的科研人员及工程技术人员,特别适用于研究生及以上学历的研究者。; 使用场景及目标:①研究风光等可再生能源在离网并网条件下驱动制氢、合成氨系统的最优容量配置与运行调度策略;②掌握基于数学规划(如混合整数线性规划)的能源系统多目标优化建模方法,实现投资成本、运行成本与碳排放的综合优化;③为实际电-氢-氨耦合示范项目的系统设计、经济性评估与运行决策提供仿真工具与量化分析支持。; 阅读建议:建议结合提供的Python代码进行实践操作,重点关注模型的目标函数构建、约束条件(如能量平衡、设备运行特性、电解槽动态响应等)的数学表达与求解器调用流程,宜配合相关专业文献深入理解合成氨反应热力学、电解槽效率模型等关键技术细节,并尝试对同边界条件(如电价、氢气价格、风光资源禀赋)进行敏感性分析,以深化对系统优化机理的理解。
内容概要:本文《2026外贸出海下半年新打法白皮书》系统梳理了2026年上半年中国外贸发展的五大关键转折与六大新变量,揭示了外贸行业从“总量增长”转向“结构性分化”的现实。文中指出,传统代工模式和单一市场依赖型企业正面临生存危机,而“新三样”(电动汽车、锂电池、光伏)及“新新三样”(AI算力、机器人、创新药)成为出口增长新动能。同时,AI正重构B2B采购决策链路,合规门槛全面提升,市场重心向“一带一路”国家转移。在此背景下,作者提出下半年三大出路:换赛道、做减法、用AI优化流程,并提供了90天落地行动路径。; 适合人群:从事外贸出口业务的企业主、管理者及从业者,尤其是面临转型压力的传统制造型外贸企业负责人,以及希望把握新兴市场与技术趋势的中小企业决策者。; 使用场景及目标:①帮助企业识别当前外贸环境中的结构性变化与风险点;②指导企业制定切实可行的转型优化策略,如市场多元化、AI工具应用、合规升级等;③提供可执行的三个月行动计划,助力企业止血、试水与复盘。; 阅读建议:此白皮书兼具宏观洞察与微观实操,建议结合企业自身情况进行逐项对照分析,重点关注客户集中度、现金流、合规状态等诊断指标,并优先落地AI工具与市场多元化试点,避免空谈战略而忽视执行细节。
内容概要:本文围绕基于AIC与BIC准则的三变量Copula联合分布概率测算展开研究,系统阐述了如何利用赤池信息准则(AIC)和贝叶斯信息准则(BIC)科学选择最优的单变量边缘分布函数,并进一步通过AIC准则筛选出最适宜的三变量Copula函数类型,从而构建高精度的联合概率分布模型。研究采用Matlab编程实现全流程,涵盖数据预处理、边缘分布拟合、Copula函数族比较、模型评估及联合概率计算等关键环节,特别适用于存在非线性依赖和尾部相关性的复杂多变量系统,如能源、金融、环境等领域的风险联合分析。文中强调了模型选择的统计严谨性与算法实现的可重复性,为极端事件的风险评估与确定性量化提供了可靠的技术路径。; 适合人群:具备扎实的概率统计学基础和Matlab编程能力的科研人员、工程师及数据分析从业者,尤其适合从事电力系统可靠性分析、金融风险管理、气候变化研究、水资源管理等涉及多变量联合概率建模的领域研究人员; 使用场景及目标:①解决传统线性相关假设无法捕捉的复杂非线性依赖与尾部相关问题;②精确评估多个极端事件同时发生的联合发生概率,提升系统风险预警与可靠性分析水平;③为确定性量化、风险情景生成、优化调度及决策支持系统提供坚实的概率基础; 阅读建议:建议读者结合所提供的Matlab代码进行动手实践,深入理解AIC/BIC在模型选择中的判别机制,掌握边缘分布拟合与Copula函数选取的核心技术细节,并尝试将该方法迁移应用于自身的实际研究数据中,以验证和拓展其应用价值。
内容概要:本文研究了基于阶跃响应的V-Tiger自动增益调整PID控制器优化方法,并提供了完整的Matlab代码实现。通过深入分析系统的阶跃响应特性,提出了一种适用于V-Tiger系统的PID控制器参数自整定策略,旨在显著提升控制系统的动态响应性能、稳定性和鲁棒性。文章系统阐述了PID控制的基本原理、增益自动调整机制以及优化算法的设计思路,重点介绍了如何利用阶跃响应数据辨识系统特征,并据此实现比例、积分、微分参数的智能化寻优。通过详尽的仿真实验验证了该方法相较于传统整定方式在响应速度、超调量和抗干扰能力方面的优越性,为复杂工况下的高精度自动控制提供了有效的技术方案。; 适合人群:具备自动控制理论基础和Matlab编程能力,从事控制工程、自动化、电气工程、机器人技术等领域的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于需要高精度、强鲁棒性实时控制的工业系统中,如精密电机驱动、机器人伺服控制、电力电子变换器、过程控制等;②用于教学与科研中深化对PID控制算法本质的理解,探索先进自整定技术的创新与改进;③为目标控制系统提供一种基于实测动态特性的自动化参数整定解决方案,有效降低对专家经验的依赖,大幅减少人工调试的时间与成本。; 阅读建议:建议读者结合提供的Matlab代码进行仿真复现与调试,重点关注阶跃响应数据的采集与特征提取方法、PID参数优化寻优的具体算法流程(如目标函数构建、寻优迭代过程),以及控制系统各项性能评价指标的分析,从而全面掌握该优化方法的核心技术细节与实际应用要点。
内容概要:本文围绕“基于粒子群算法优化FCM聚类的居民用电行为分析研究”展开,提出了一种结合粒子群优化算法(PSO)与模糊C均值聚类(FCM)的混合智能优化方法,旨在提升居民用电行为分类的准确性与鲁棒性。通过引入PSO算法优化FCM的初始聚类中心选择,有效克服了传统FCM算法易陷入局部最优、收敛速度慢及对初始值敏感等问题,显著提高了聚类的稳定性和精度。研究在Matlab平台上完成了算法的设计与实现,并利用实际居民用电负荷数据进行实验验证,结果表明该方法能够高效识别用户的用电模式,实现精细化用户画像划分,为电力企业开展需求侧管理、制定差异化电价策略和个性化用电服务提供了科学依据和技术支持。; 适合人群:具备电力系统分析、数据挖掘智能优化算法基础的科研人员、电气工程及相关专业的研究生,以及从事智能电网、负荷预测与用户行为分析的工程技术与管理人员。; 使用场景及目标:①应用于居民用电负荷数据的聚类分析与行为模式识别;②优化电力用户细分策略,支撑精准营销与需求响应决策;③作为智能优化算法与聚类技术融合的教学案例,服务于相关课程设计与科研实践。; 阅读建议:建议结合Matlab代码深入理解PSO-FCM算法的实现细节,重点关注种群初始化、适应度函数设计及聚类结果评估等关键环节,鼓励尝试将该框架拓展至其他智能算法(如遗传算法、灰狼优化器)与聚类模型的融合,以进一步探究其在同场景下的性能表现与优化潜力。
内容概要:本文提出了一种基于递进事件触发框架的孤岛微电网DoS攻击容错二次协同控制方法,旨在解决分布式控制系统中通信资源受限与恶意拒绝服务(DoS)攻击带来的稳定性挑战。通过构建混合动态事件触发机制,有效降低系统通信频率与资源消耗,同时结合非奇异终端滑模控制与强化学习算法,设计了具备攻击容忍能力的协同控制策略,实现了电压频率的精确恢复及有功无功功率的均衡分配。该方法充分考虑了执行器饱和与外部扰动因素,引入扰动观测器进行补偿,并通过Lyapunov稳定性理论证明系统收敛性,最终在Simulink平台上完成仿真实验,验证了所提方案在动态响应性能、抗干扰能力及通信效率方面的优越性。; 适合人群:具备电力系统自动化、现代控制理论、网络信息安全及MATLAB/Simulink仿真基础,从事微电网控制、智能电网安全防护分布式能源系统研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于孤岛运行模式下的微电网二次控制,提升系统在通信受限和网络攻击下的鲁棒性与自治能力;②为事件触发控制、容错控制与网络安全防御在能源互联网中的深度融合提供理论依据与仿真范例;③服务于来智能配电系统的安全设计、控制策略优化与风险评估。; 阅读建议:建议结合文中系统建模、控制器设计与稳定性分析部分进行逐层推导,重点理解递进事件触发机制的设计逻辑与DoS攻击检测机制的实现方式,宜配合Simulink模型与MATLAB代码开展仿真实验,深入掌握算法参数整定与性能优化方法。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值