【dubbo3.x trace组件分享】
背景
在微服务系统里服务非常的分散,服务日志也分散在各处,多个服务没有统一并且唯一的检索条件,导致问题排查难度很大,因此trace链路追踪技术就应运而生。
一、trace-dubbo组件介绍
github:https://github.com/zbrave429/dubbo-trace
dubbo-trace基于dubbo3.x实现了traceId,spanId链路传递,使用非常简单,代码0侵入,maven直接引入即可
二、设计原理
2.1 原理图
官方文档:https://dubbo.apache.org/zh/docs/v3.0/references/features/attachment/

从图中可以看到,左边为consumer,右边为provider
在consumer端filter里面setAttachment 放入trace参数,在provider端filter里面getAttachment获取trace参数,执行后续处理。
原理已经很清楚了,接下来就是干
2.2 实现方案
- 请求入口将trace信息缓存到ThreadLocal内和Log参数
- consumer在发起dubbo调用时从ThreadLocal内获取trace信息设置到Attachment参数内
- provider接收到请求后从Attachment获取到trace信息缓存到ThreadLocal和Log内
2.2.1 consumer端实现
// CommonConstants.CONSUMER 客户端过滤器
@Activate(group = {CommonConstants.CONSUMER})
public class TraceConsumerFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 1.从ThreadLocal内获取trace信息
Tracer tracer = TraceContext.get();
if (!Objects.isNull(tracer)){
// 2.trace信息设置到Attachment内
setTrace(invocation, tracer);
}
// 3.执行调用
return invoker.invoke(invocation);
}
}
2.2.2 provider端实现
// CommonConstants.PROVIDER
@Activate(group = {CommonConstants.PROVIDER})
public class TraceProviderFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
// 1.获取attachments参数
Map<String, String> attachments = invocation.getAttachments();
// 2.构建trace信息
Tracer tracer = buildTracer(attachments);
try{
// 3.将trace信息存到ThreadLocal内和Log参数内
initTraceContext(tracer);
// 4.执行业务
return invoker.invoke(invocation);
} finally {
// 5.清除trace信息,防止线程污染
removeTraceContext();
}
}
}
2.2.3 traceId和spanId生成算法
不在本篇文章讨论范围,感兴趣可以自行clone代码
git clone https://github.com/zbrave429/dubbo-trace.git
2.2.4 ThreadLocal局限性
理想状态下trace信息应该在一次请求的所有执行线程内进行传递,但是ThreadLocal无法在子线程内传递,因此java引入了InheritableThreadLocal ,InheritableThreadLocal可以解决主线程创建子线程时,子线程获取缓存数据的场景。但是目前更多的是使用线程池,线程池一般在服务启动时初始化,就导致通过线程池执行异步操作trace信息丢失的问题。
为了彻底解决这个问题我们可以引入阿里的线程池组件transmittable-thread-local,dubbo-trace组件已经集成,原理和使用大家可以自行百度
或参考 https://github.com/zbrave429/async-task
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.12.4</version>
</dependency>
三、使用步骤
3.1.clone项目
git clone https://github.com/zbrave429/dubbo-trace.git
3.2.打包
maven install
3.3.maven工程引入依赖
<dependency>
<groupId>com.brave</groupId>
<artifactId>dubbo-trace</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
3.4.日志输出配置
日志输出格式内增加配置 %X{traceId} %X{spanId}
- %X{traceId}:traceId参数
- %X{spanId}:spanId参数,调用树
3.5.服务入口调用初始化方法
/**
* IdGenEnum idGenEnum id生成器类型,目前支持两种
* UUID - 通过UUID生成的lang整形19位带符号数字
* CURRENT_TIME - 通过(时间戳11位 + 自增ID4位 + 随机数4位)生成的19位字符串
*
* prefix 前缀,拼接在系统内置的算法生成的字符串之前,CURRENT_TIME模式下才有效,
* 用来增强traceId的唯一性,例如:prefix = IP + APPKEY
*/
TraceContext.init(IdGenEnum idGenEnum, String prefix);
总结
希望本篇文章能对大家有所帮助,后续会持续在这个项目上集成更多实用的功能,例如:压测标记传递,泳道测试环境,线上测试链路,打点监控等。github上点个star,多多支持!
【dubbo3.x trace组件分享】的更多相关文章
- 分析easyswoole3.0源码,Trace组件(四)
前文,我们访问地址的时候服务端会输出类似trace信息.那么原理是什么呢?其实es3已经把这个独立出来作为单独组件了,名字叫做Trace组件 在demo里的调用原理是 EasySwooleEvent: ...
- Winform自动更新组件分享
作者:圣殿骑士 出处:http://www.cnblogs.com/KnightsWarrior/ 关于作者:专注于微软平台项目架构.管理和企业解决方案.自认在面向对象及面向服务领域有一定的造诣,熟悉 ...
- 【手记】小心在where中使用NEWID()的大坑 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题 【C#】组件分享:FormDragger窗体拖拽器 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
[手记]小心在where中使用NEWID()的大坑 这个表达式: ABS(CHECKSUM(NEWID())) % 3 --把GUID弄成正整数,然后取模 是随机返回0.1.2这三个数,不可能返回其它 ...
- vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
一.前言 三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习. 图片的上传之前都是用的插件(ajaxupload), ...
- Android Cocos2d-x游戏集成友盟社会化组件分享功能
最近在帮助开发者集成友盟社会化组件的过程中,发现游戏的集成过程遇到一些困难,而Cocos2d-x具有较好的代表性,因此整理了一篇关于Android Cocos2d-x游戏集成友盟社会化组件指南,由于本 ...
- Android 友盟社会化组件-分享实现
本文章链接地址:http://dev.umeng.com/social/android/share/quick-integration 分享快速集成 1 产品概述 友盟社会化组件,可以让移动应用快速具 ...
- vue 表格组件分享
分享一款自己写的table组件 用起来还算简单好用 (先介绍使用方法(ts版本的)) 引入组件不多说 import jTable from '../comp/comp/table/table.v ...
- 【C#】组件分享:FormDragger-窗体拖拽器
适用:.net2.0+ winform项目 介绍: 类似QQ.迅雷等讲究UI体验的软件,都支持在窗口内多处地方拖动窗口,而不必老实巴交的去顶部标题栏拖,这个组件就是让winform也能这样随性拖拽,随 ...
- 【C#】组件分享:FormDragger窗体拖拽器
适用:.net2.0+ winform项目 介绍: 类似QQ.迅雷等讲究UI体验的软件,都支持在窗口内多处地方拖动窗口,而不必老实巴交的去顶部标题栏拖,这个组件就是让winform也能这样随性拖拽,随 ...
随机推荐
- 获取缓存文件大小并清理 By HL
通常用于删除缓存的时,计算缓存大小 //单个文件的大小 - (long long) fileSizeAtPath:(NSString*) filePath{ NSFileManager* manage ...
- HTML基础笔记整理
「学习笔记」HTML基础 前言 勤做笔记不仅可以让自己学的扎实,更重要的是可以让自己少走弯路.有人说:"再次翻开笔记是什么感觉",我的回答是:"初恋般的感觉". ...
- PHP面试笔试宝典
PHP面试笔试宝典 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. PHP题目 一.单例模式是在应用程序中最多 ...
- C#设置进程PATH环境变量值解决某些Win32DLL找不到路径问题
C#.NET通过设置当前进程PATH环境变量值解决某些Win32DLL找不到路径问题 以下函数设置PATH环境变量值(请注意:该环境变量为当前进程的环境变量,非系统环境变量)用于解决在调用某些Win3 ...
- NPM 错误、问题等汇总
一. npm的作用就是对Node.js依赖的包进行管理,也可以理解为用来安装/卸载Node.js需要装的东西 二. 1. 修改npm配置为淘宝的源下载: npm install -g cnpm --r ...
- HTML5知识点笔记
1.HTML是一种标记语言 2.HTML元素不区分大小写 //可以在xss绕过waf时使用 3.<code></code>为空元素标签 <code/>为自闭合标签 ...
- Eureka工作原理及心跳机制
Eureka原理 1.基本原理上图是来自eureka的官方架构图,这是基于集群配置的eureka:处于不同节点的eureka通过Replicate进行数据同步Application Service为服 ...
- 【转】可见性、原子性和有序性问题:并发编程Bug的源头
如果你细心观察的话,你会发现,不管是哪一门编程语言,并发类的知识都是在高级篇里.换句话说,这块知识点其实对于程序员来说,是比较进阶的知识.我自己这么多年学习过来,也确实觉得并发是比较难的,因为它会涉及 ...
- Collection接口和Map接口的 size 方法和 isEmpty方法
一.Collection接口的 size 方法和 isEmpty方法 int size(); 返回列表中元素的数目,如果这个列表包含超过Integer.MAX_VALUE,则返回Integer.MAX ...
- navicat12.0.24安装注意事项
关闭防火墙并断网,或者不要改变安装路径,或者换一个注册机 链接:https://pan.baidu.com/s/1AvEuD6TWGOCisSctF7pcbg 提取码:o4wp