skywalking 核心概念
TraceSegment
在 skywalking 中,TraceSegment 是一个介于 Trace 与 Span 之间的概念。它是 Trace 的一段,包含多个 Span。
在微服务架构中,一个请求基本都会涉及跨进程(以及跨线程)的操作,例如, RPC 调用、通过 MQ 异步执行等,处理一个请求就需要涉及到多个服务的多个线程。TraceSegment 记录了一个请求在一个服务中的执行流程(即 Trace 信息)。将该请求关联的 TraceSegment 串联起来,就能得到该请求对应的完整 Trace。
Span
skywalking 中 span 共有三种类型:
EntrySpan
当请求进入服务时会创建 EntrySpan 类型的 Span,它也是 TraceSegment 中的第一个。
LocalSpan
是在本地方法调用时可能创建的 Span 类型。
ExitSpan
当请求离开当前服务,进入其他服务时会创建 ExitSpan 类型的 Span。
Span 管理
我们来看下 span 的管理,当请求通过 Tomcat 的时候,创建一个 EntrySpan,然后调用 EntrySpan 的start()
方法,会把 EntrySpan 放入到 span 队列的 activeSpanStack 中,当请求经过 springMvc 的时候,不会再创建 EntrySpan,只会重新调用 EntrySpan 的start()
方法,当在业务方法中调用接口的first()
方法的时候,会创建一份 LocalSpan,并且把 LocalSpan 添加到 activeSpanStack 中,当first()
方法调用结束的时候,LocalSpan 会出栈,当调用业务的second()
方法的时候,会创建一份 LocalSpan,并且把 LocalSpan 添加到 activeSpanStack 中,当second()
方法调用结束的时候,LocalSpan 会出栈。接下来使用 Feign 接口远程调用greeting()
方法的时候,会创建一个 ExitSpan,然后将 ExitSpan 添加到 activeSpanStack 中,当greeting()
方法调用结束的时候,会将 ExitSpan 出栈,最后请求结束,第一个 EntrySpan 出栈。
跨进程传播
ContextCarrier 是 TracingContext 上下文的搬运工,负责在进程之间搬运 TracingContext 的一些基本信息,其中就包括 Trace ID。服务端负责从 ContextCarrier 中提取链路信息,而客户端则通过向 ContextCarrier 注入链路信息从而传输到服务端。
跨线程传播
TracingContext 对跨线程传播的支持涉及capture()
方法和continued()
。跨线程传播时使用 ContextSnapshot 为 Context 上下文创建快照,在异步线程中通过快照信息还原 TraceSegment 信息。
Skywalking 链路传播框图
我们在一次调用里面,所经历的一个线程,会生成一个 TraceSegment 。这里它经历了 4 个线程,不管是否跨 JVM ,A 里面 1 个,B 里面 1 个,B 里面的 New Thread 1 个,C 里面 1 个,所以它经历了四个线程后就会生成四 TraceSegment 对象。一次调用经过一个线程就会产生一个 TraceSegment,整个 Trace 的调用链就是由多个 TraceSegment 构成的。
版权声明: 本文为 InfoQ 作者【淡泊明志、宁静致远】的原创文章。
原文链接:【http://xie.infoq.cn/article/cd78dd118698c9a016684948d】。未经作者许可,禁止转载。
评论