Opentracing 调用链服务端埋点

1 前言

通过一个最简单的代码例子来看使用opentracing在服务端埋点的逻辑。因为调用链的抽象模型都是来自dapper这篇论文,所以其他的方式也是类似,只是接口方法上稍有不同。

2 关于服务端埋点

主要流程看上是:

  • 1) 收到请求
  • 2) 从通信协议(如常用的HTTP header)中解出客户端传递的trace;
  • 3) 构造span
  • 4) 保存span
  • 5) 服务端返回请求
  • 6) 关闭span,将span的数据结构上传到调用链的数据存储节点。

下面结合一个例子中的额使用看下2 3 4 6四个调用链埋点步骤具体做了哪些事情。

3 主要流程

以最典型的http服务端为例。如下面是个http服务端的里,一般的最简单的一个http服务端写出来可能是这样,从request中解到请求的参数,然后执行服务端处理的逻辑,然后结果写到response。

看下如果在这端代码中加入埋点,能把对这个接口的调用跟踪起来。

下面是埋点的接口,在构造handler的时候通过了一个wrapper方法加入了埋点。即将一个handler Decorator成了另外一个handler,即在业务的handler上加入了埋点功能。

那么这修饰器的逻辑就是埋点的逻辑了。详细的解析这部分代码来看使用opentracing在服务端埋点的逻辑。

代码中间的注释了下这4个步骤,这里详细描述下:

步骤1 从Request中解出SpanContext,即调用Tracer接口上定义的Extract方法。

Opentracing定义了inject和extract方法,将span的信息(SpanContext)编码到carrier中。当一个埋点的客户端发起请求时,span信息就加到了请求内容中。

Extract和Inject是跨进程Tracing的主要机制,一个span的发起方是在客户端,响应方是在服务端,要共享一个调用Id,在tracing中术语是spanId,需要有一种机制能从客户端发出来,在服务端再解出来(当然实际使用中不止这点信息,详细参照Span的数据结构和trace的模型定义),需要在跨进程调用的时候能传递出来,不管是RPC,消息队列还是HTTP等其他协议的调用。

Extract方法作为opentracing Tracer的三个基础方法之一,在opentracing接口中被定义。

在各个Opentracing的实现中,会有对应的实现。如openzipkin/zipkin-go-opentracing 有对应的实现:

对于http类型的服务调用也就是从http header里解出客户端传来的trace信息。

关于extract和inject详细可以参照opentracing中这部分描述。

步骤2 启动span

如果可以解出来客户端的span,则说明这个请求的客户端已经埋点,服务端的处理会和客户端在一个trace上,如果未解出来,则客户端未埋点,或者埋点数据丢失,在服务端重新创建一个span,即开始一个新的trace。在span的模型中,对客户端Span存在也是有两种风格的处理一种是服务端构造一个新的Span,parentspan设为客户端那个span,另外一种是直接更新解出来客户端的那个span。

步骤3 保存span

在服务端的请求过程中需要,需要保存span信息,以便在业务需要的时候可以访问到span。只有这样业务代码才可以设置自定义的tag,记录event,或者根据需要创建子span(如果需要对服务内部的调用详情在追踪的话)。

在openttracing的go的埋点方中是将span保存到到Request的context中,后面处理请求的业务代码会根据需要从Request中得到Context。关于为什么没有使用threadlocal而是使用Contex参照关于context的设计思想。

gocontext.go其实就是把span作为一个固定key的value设置给context,并借助context向下传递。

如在前面例子中sumHandler的业务方法Sum就可以从Request的context中得到当前span并进行操作。

其中SpanFromContext是从Context中解出对应的对象

步骤4 结束span。就是服务端调处理完毕调用结束span。主要是标注span结束时间,同时通过recorder接口上报span。

这个方法定义在opentracing的span接口上,一般实现是这样(如zipkin-go-opentracing中)

即记录span结束时间,并通过recordspan保存span,这就是调用方span的埋点数据。通过一种通道(实现了recorder接口的方法)上报到调用链的服务中心去,供调用链检索。

zipkin-recorder.go

将rawspan的数据格式转换为,然后通过一个collector上报到服务端。

上报方式collector可以有不同的实现,可以有基于http,也可以由基于消息方式的。

zipkin的span定义在这里,包括比较完备的解释参照原文件中注释。

4 最后

服务端埋点这部分逻辑,需要在服务端有个合适的地方修改,类似过滤器,或者相应请求的公共地方,避免在每个业务请求中加代码。

除了例子中的这个 zipkin-go-opentracing ,还有很多调用链的项目实行了opentracing的规范和定义。

 

 

 

 

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自idouba

本文链接地址: Opentracing 调用链服务端埋点


, , ,

No comments yet.

发表评论