Skywalking 探针上下文传播模型:
header 头中填充 key:sw8 value 是
1-YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDI=-YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDA=-2-b2JzZXJ2YWJsZQ==-MzNlZGIzYzU2NGE5NGYxNWIwNWMwYzczZTMxNTMzYjFAMTcyLjMxLjExLjcy-R0VUOi9jYWxs-bG9jYWxob3N0OjgwODg=
拆解一下:
1、(是否需要采样)1-
2、(TraceId;解码后:bd57d0c234554012b5c62f38c0e1e8a9.71.17104823418880002)
YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDI=-
3、(父SegmentId;解码后:bd57d0c234554012b5c62f38c0e1e8a9.71.17104823418880000)
YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDA=-
4、(父SpanId)2-
5、(父服务实例 ID,上一级进程的注册 ID;解码后:observable)
b2JzZXJ2YWJsZQ==-
6、(入口实例服务的注册 ID;解码后:33edb3c564a94f15b05c0c73e31533b1@172.31.11.72)
MzNlZGIzYzU2NGE5NGYxNWIwNWMwYzczZTMxNTMzYjFAMTcyLjMxLjExLjcy-
7、(GET:/call)
R0VUOi9jYWxs-
8、(请求的目标地址,base64 解码后是:localhost:8088)
bG9jYWxob3N0OjgwODg=协议内部使用“-”相连,所有字符串类型都会使用 base64 编码;
构建上下文传播
构建的真实 traceId 为:bd57d0c234554012b5c62f38c0e1e8a9.71.17104823418880003
其中父SegmentId 和父spanId 都是 0;
1-YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDM=-MA==-0-b2JzZXJ2YWJsZQ==-MzNlZGIzYzU2NGE5NGYxNWIwNWMwYzczZTMxNTMzYjFAMTcyLjMxLjExLjcy-R0VUOi9jYWxs-bG9jYWxob3N0OjgwODg=
说明一下:这里构建的上下文传播模型,是由对应的服务发起方构建,然后传递给下游服务的。
比如 A 服务此时需要通过http 或者 rpc 调用 B 服务,此时则需要将当前使用的 traceId 以及当前 A 服务的 segmentId 和我当前 A 服务调用你时的 spanId,这些信息传递给下游。这些信息就是需要构建为一个上下文传播模型。传播给下游使用的。
将对应的 TraceId 修改为:bd57d0c234554012b5c62f38c0e1e8a9.71.17104823418880005
其中父Segmentid 是 0,父SpanId 是 5:
1-YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMDU=-MA==-5-b2JzZXJ2YWJsZQ==-MzNlZGIzYzU2NGE5NGYxNWIwNWMwYzczZTMxNTMzYjFAMTcyLjMxLjExLjcy-R0VUOi9jYWxs-bG9jYWxob3N0OjgwODg=
如上两个图可知:VNode:0 ;
这里的 VNode 表示VirtualNode(虚拟节点)
这里的0表示当前该虚拟节点的 SegmentId;(因为我是自己指定的 SegmentId 是 0,所以此处显示的则是 0)
每个 VNode:0 下面都有一行小字:
1、Broken - VirtualNode #0 (这里的#0 表示当前的 spanId 是 0)
2、Broken - VirtualNode #5 (#5 表示当前该行数据的 spanId 是 5)
由于此处我们所指定的,父Segmentid 是 0,父SpanId 是 5
所以我们此时最终的 GET/end 链路,则是挂靠在 Broken - VirtualNode #5 这个节点上。
即当前该 GET/end 这条 Segment 链路,对应的父级是Segment Id 为 0,spanId 为 5 的这个节点下。
约定 APP 的传递 ID
首先上述真实的上下文传播中定义的如:请求的目标地址,请求的方法名,这些在链路上无法体现出来,因为只能看到当前是一个 VirtualNode(虚拟 Node);
因为本身该 Node 中的 Segment 数据本身是并没有被上传的,所以该所指定的父Segment 其实也是一个不存在的 Segment;所以在链路明细中去看的时候就会发现该 VirtualNode 的开始时间是一个1970-01-01 08:00:00 这样一个错误的时间。
因为该父Segment 本身的数据是并没有上报到云端的,我们只是构建了这样一个虚拟的父SegmentId,所以本身就不知道父Segment 是何时开始的,所以显示一个错误的时间,这个也正常。
除了构建上下文传播模型中的这个时间问题以外,上下文传播模型中的:入口实例服务的注册 ID 以及请求的目标地址,这些信息在对应的链路中都体现不出来具体的内容。所以对于这部分就可以直接定义为一个不具备价值的 base64 转码直接传播到后端就行了。
那么最终定以后的传播模型如下所示:
1-YmQ1N2QwYzIzNDU1NDAxMmI1YzYyZjM4YzBlMWU4YTkuNzEuMTcxMDQ4MjM0MTg4ODAwMTU=-MA==-0-QW5kcm9pZC1BcHA=-MA==-MA==-MA==其中 traceId 还是需要的,MA== 表示 0 ,所以此处的父SegmentId 就是0,然后父SpanId 也是 0;
QW5kcm9pZC1BcHA= 表示 Android-App 的 base64 表现方式;
其它的 MA==均是用0 来表示了;
此时可能存在的疑问是,此处的实例 Id:Android-APP 这个标识有用吗,在刚才的链路中也没有体现出来啊。有用的,这个标识在最终渲染流量拓扑图的时候是有用的。如下所示:

可以看出来这个流量的发起方是由 Android-App 发起的。