Dubbo链路追踪??生成全局ID(traceId)

全局 traceId


关于链路追踪,在微服务的趋势下,一次调用的日志信息分布在不同的机器上或目录下,当需要看一条链路调用所有的日志信息时,这是个比较困难的地方,我们虽然有ELK , Sentry等日志异常收集分析工具, 但是如何把信息串起来也是一个关键的问题。 我们一般的做法是在系统调用开始时生成一个traceId , 并且它伴随着一次调用的整个生命周期 。 当一个服务调用另外一个服务的时候,traceId 则向下透传,全局使用唯一一个。


一、通过修改Dubbo源码实现全局traceId(侵入性高不建议使用)


我们通过分析源码可以知道客户端在调用服务段进行服务消费时,实际上发送的是封装过的Request实体 ,Data为Invocation实体对象(接口签名,参数类型,参数值,及attachment附件)


final class HeaderExchangeChannel implements ExchangeChannel {
...
public ResponseFuture request(Object request, int timeout) throws RemotingException {
if (closed) {
throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!");
}
// create request.
Request req = new Request();
req.setVersion("2.0.0");
req.setTwoWay(true);
req.setData(request);
DefaultFuture future = new DefaultFuture(channel, req, timeout);
try {
channel.send(req);
} catch (RemotingException e) {
future.cancel();
throw e;
}
return future;
}
...
}

通过源码可知 request是入参,其他参数均为固定,所以只能在request中做文章。


代码涉及到的类有


TraceIdUtil : 链路追踪全局ID生成器InvokerInvocationHandler : 消费端Invocation处理器DubboProtocol : Dubbo协议处理入口,内有服务提供者处理请求数据信息的Handler处理器

TraceIdUtil源码如下


public class TraceIdUtil {

private static final ThreadLocal TRACE_ID = new ThreadLocal();

public static String getTraceId() {
if(TRACE_ID.get() == null) {
String s = UUID.randomUUID().toString();
setTraceId(s);
}
return TRACE_ID.get();
}

public static void setTraceId(String traceId) {
TRACE_ID.set(traceId);
}
}

由Dubbo线程模型图示可知,Dubbo客户端调用实际上通过JavassistProxyFactory获取的是Proxy代理对象。


代码如下


public class JavassistProxyFactory extends AbstractProxyFactory {
...
@SuppressWarnings("unchecked")
public T getProxy(Invoker invoker, Class[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
...
}

其中 InvokerInvocationHandler 调用数据的处理及rpc调用实体的封装过程。所以我们需要在调用的起始位置添加traceId信息 。


其次是服务提供者进行请求处理过程: DubboProtocol的requestHandler 请求处理器(不明白请详读服务Dubbo服务暴露过程源码)


将traceId 从RpcInvocation 的attachment属性中取出 ,传给TraceIdUtil 方面后续调用过程使用。


扩展Provider端Filter (无侵入性,建议使用)


创建Filter 服务提供者端扩展


/**
* Created with IntelliJ IDEA.
*
* @author: bakerZhu
* @description:
* @time: 2018年09月09日
* @modifytime:
*/
@Activate(group = {Constants.CONSUMER, Constants.PROVIDER} , order = -9999)
public class GlobalTraceFilter implements Filter {

@Override
public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
String traceId = invocation.getAttachment("traceId");
if(!StringUtils.isBlank(traceId)) {
RpcContext.getContext().setAttachment("traceId",traceId);
}else { // 第一次发起调用
RpcContext.getContext().setAttachment("traceId", UUID.randomUUID().toString());
}
return invoker.invoke(invocation);
}
}

资源文件夹下创建 META-INF/dubbo 文件夹 创建com.alibaba.dubbo.rpc.Filter 文件,并编辑文件内容 gtrace=com.alibaba.dubbo.rpc.filter.GlobalTraceFilter


疑惑点 为什么设置Dubbo上下文的attachment调用时会出现在 RpcInvocation中


详见 AbstractInvoker.invoke(Invocation inv) 方法


public abstract class AbstractInvoker implements Invoker {
public Result invoke(Invocation inv) throws RpcException {
......
Map context = RpcContext.getContext().getAttachments();
if (context != null) {
invocation.addAttachmentsIfAbsent(context);
}
if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) {
invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
}
RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
......
}
}

将上下文的“附件信息”拷贝到RpcInvocation中


文章来源:https://my.oschina.net/LucasZhu/blog/2046356
推荐阅读:https://www.roncoo.com/course/list.html?courseName=Dubbo

相关文档

  • 小米电视2s音频输出能直接接耳机吗
  • 餐饮业面试自我介绍
  • java modbus_基于Java的Modbus通讯
  • word如何提取附件表格
  • 9年级语文同步练习答案
  • 圣诞节趣味短信祝福语:圣诞节祝福语,圣诞节祝福短信
  • Go unkown reversion问题解决
  • 华为手机安装未知应用权限在哪
  • 用西红柿胡萝卜黄瓜可以做什么菜
  • ReentrantLock与AQS(AbstractQueuedSynchroizer)
  • C++的反思[转]
  • 2020年大学生春季运动会主持词
  • 与电子商务有关的毕业论文
  • 咖啡和茶能不能一起喝
  • 高三活出自我作文
  • 2017关于找工作的一些感想!
  • 西方数学史上的8本名著
  • 人生理想名人名言
  • 阿里云视频点播Vod
  • 弥勒市政府工作报告
  • 当我们访问一个网站时发生了什么《Linux从小白到菜鸟》之一《网站搭建》[这一系列科普教程将教会你搭建一个简单的网站]
  • 医院妇科年终工作总结范文
  • 人生哲理小故事精选汇总
  • 美国独立战争和南北战争的相同点和不同点
  • 忘恩负义的狗寓言故事
  • 【图形分类三种方法】《图形的二次分类》教学反思范文
  • 假体隆胸能不能哺乳隆过胸了还能喂奶么
  • 并不是所有的母爱都可以创造奇迹
  • 基础会计测试题及答案
  • 环境卫生承诺书范文通用3篇
  • 电脑版