zipkin:自定义链路传播(四)

本文介绍了在无法侵入消息体进行链路跟踪的情况下,如何通过RocketMQ的meta信息实现链路传播。详细讲解了zipkin链路信息的内容,如SpanId、ParentSpanId和TraceId,并阐述了官方dubbo链路传播方式。接着,文章提出了自定义链路传播方案,利用setter和getter定义传播行为,通过注入和提取链路信息实现跟踪。最后,展示了在RocketMQ producer和consumer中应用自定义链路传播的方法。
摘要由CSDN通过智能技术生成
  • 链路传播定义的是中间件的Server/Producer端将链路信息注入到载体的行为;以及Client/Consumer如何从载体中抽取链路信息的行为;
  • 载体可以是消息体或者请求体。

背景

上一篇提到通过zipkin:实现zipkin-spring-boot-starter(三)包降低接入链路跟踪门槛以后,开发同学接入的积极性提高,同时也反馈目前支持链路跟踪的中间件满足不了需求,比如说无法跟踪通过redis实现的轻量级mq以及阿里云的mns等。

但是站在框架维护者的角度考虑:对这类消息中间件的链路跟踪非常棘手,为什么?
因为这类消息中间件没有扩展机制,开发者发送到消息队列中的业务消息就是就是消息的全部。若要对消息进行链路跟踪,那么势必会对消息体进行侵入:将链路信息放到业务消息中。若侵入用户消息体,那么就要对业务消息体的格式有强要求,这是不行的、会引发出很多问题。

那RocketMQ为什么没有这个问题呢?因为RocketMQ将消息体分成了两个部分:meta信息和业务数据;不管消息体中的业务数据如何变化都可以将链路上下文放到meta信息中,从而实现链路跟踪。

所以现在面临的问题:

  1. 框架维护者的角度:不能以侵入业务消息体为代价进行链路跟踪
  2. 业务开发者的角度:需要对此类消息中间件进行链路跟踪

现在是一个两难的局面,只能大家各往后退一步:

  1. 框架维护者:提供链路信息的提取和注入工具
  2. 业务开发者:自行在生产端将当前链路信息注入到消息体中;在消费端提取消息体中的链路信息提取出来

嗯,也是一个不错的方案!

zipkin链路信息

聊链路传播之前,我们来看看链路传播到底传播了哪些信息,这是从dubbo链路提取出来的链路信息:

  • X-B3-SpanId=c4d1b2bf028149ec
  • X-B3-ParentSpanId=bfb6542ce3a8f6ca,
  • X-B3-Sampled=1
  • X-B3-TraceId=bfb6542ce3a8f6ca

简单解释一下:

  • X-B3-SpanId:当前span的id
  • X-B3-ParentSpanId:当前span的父spanid
  • X-B3-Sampled:采样标识符,即是否上报的zipkin-server端
  • X-B3-TraceId:当前trace的id

链路传播

在官方的代码中,链路传播分为以下几个步骤:

1. 定义具体的传播行为

  • brave.propagation.Propagation.Setter:将链路信息set到指定的载体中
  • brave.propagation.Propagation.Getter:将链路信息从指定的载体中get出来

2. 提取或者注入链路信息

  • brave.propagation.Propagation#injector:与Setter结合使用,将内存中的链路信息注入到载体中
  • brave.propagation.Propagation#extractor:与Getter结合使用,将载体中的链路信息提取到内存中

ok,进入实操阶段,先看看dubbo链路传播是怎样实现的

官方dubbo链路传播

1. 定义具体的传播行为:将请求体中的attachement作为链路信息的载体,把链路信息直接put到attachment中

    static final Setter<DubboClientRequest, String> SETTER =
        new Setter<DubboClientRequest, String>() {
   
            @Override public void put(DubboClientRequest request, String key, String value) {
   
                request.putAttachment(key, value);
            }
        };

2. 提取或者注入链路信息:提取内存中的链路信息并放到载体中

	//1. 设置具体的链路传播行为
	TraceContext.Injector<DubboClientRequest> injector = tracing.propagation().injector(SETTER);

	//2. 从dubbo请求上下文中获取载体信息,即attachment
    Map<String, String> attachments = RpcContext.getContext()
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值