文章目录
- 原理图
- 栈机制解说
- 名词含义
- 总结
原理图
图编号: 第一排序规则: 自左向右递增 第二排序规则: 自上向下递增
栈机制解说
详解一个Http请求经过APP-1(tomcat-> springmvc -> dubbo provider)和APP-2(dubbo consumer)的调用链路
- 图1: TomcatInvokeInterceptor.beforeMethod创建EntrySpan,内部创建TracerContext上下文,TracerContext内部创建TraceSegment, EntrySpan加入TracerContext.activeSpanStack.此时span的最大栈深度和当前栈深度都是1
- 图2: MVC插件beforeMethod发现tomcat已经创建entrySpan,则复用该span,此时span的最大栈深度和当前栈深度都是2
- 图3: DubboInterceptor.before发现即将跨进程,创建ExitSpan(栈深等于1)并加入activeSpanStack
- 图4: 到达新的进程(dubboProvider端),创建一个EntrySpan,栈深为1
- 图5: DubboInterceptor.afterMethod,离开时栈深减一等于0
- 图6: 当entrySpan的栈深度为0 ,则将其加入Segment.span
- 图7: 发现activeSpanStack中没有span,说明未来不会从activeSpanStack弹出span到Segment,触发Segment上报到OAP
- 图8: ContextManager.stopSpan清空TracerContext和RuntimeContext
- 图9: 此时serviceB处理完毕,回到serviceA的dubbo消费端DubboInterceptor.afterMethod执行后stackDepth减一等于零
- 图10: 发现stackDepth为零,则将该ExitSpan移除activeSpanStack加入Segment,由于activeSpanStack还有一个EntrySpan,不进行OAP数据上报
- 图11: 此时到达MVC的afterMethod,最大栈深度为2但当前栈深度减一,由于当前栈深度不为零,则不进行出栈处理
- 图12: TomcatInvokeInterceptor.afterMethod执行后发现当前栈深度减一等于零
- 图13: 栈深度为0,则将activeSpanStack中的EntrySpan弹栈后加入Segment
- 图14: 由于activeSpanStack中无元素,触发Segment上报OAP
- 图15: 整个链路调用完毕清空TracerContext和RuntimeContext
名词含义
名称 |
解释 |
TracerContext |
当请求到达一个新的进程时,skywalking会创建或者反序列化ContextCarrier获得TracerContext |
EntrySpan |
到达新进程或流量入口span一般称为入口Span,其有两个属性currentMaxDepth和stackDepth |
TracerContext.activeSpanStack |
新创建的Span并没有加入Segment,而是加入activeSpanStack |
EntrySpan.currentMaxDepth与stackDepth |
tomcat和springMvc都适合做entrySpan,此时mvc复用tomcat的EntrySpan,但stackDepth++,currentMaxDepth++ |
TracerContext.segment |
一个segment表示一条跨进程与线程的调用链路 |
Segment.spans |
当进入插件拦截方法EntrySpan的stackDepth++,当离开插件拦截方法EntrySpan的stackDepth–,当stackDepth等于零,则从activeSpanStack弹出并加入Segment.spans |
总结
- Segment链路的数据来自于TracerContext
- 每个插件都将Span加入activeSpanStack中,进入插件拦截方法压栈或者stackDepth++,离开插件拦截方法出栈或者stackDepth–
- stackDepth = 0则弹栈移入Segment
- 当activeSpanStack无元素则向OAP上报链路数据