关于go-zero:都在还说链路跟踪那么-gozero-的链路跟踪是咋样的

44次阅读

共计 2097 个字符,预计需要花费 6 分钟才能阅读完成。

工作中,天然少不了开发去排查问题,那如果链路比拟长,客户端一个申请打进来,可能外部微服务进行了多个服务的交互,那么如果其中有一个环节呈现了问题,咱们如何定位是哪一个申请或者是说是哪一条调用链呢?

可能开发的时候或多或少会退出本人的一些示意,例如申请外面会退出 requuid,链路中波及的服务都会将这个 requuid 传下去,直到整个调用链完结

当然比拟 low 的一种形式是,在微服务交互的申请和相应中加上 requuid 字段,这个应该也是从单体服务适度到微服务开发时特地容易呈现的状况

实际上做链路跟踪,简略的形式就是在各种申请的上下文加上 traceid 就能够了,明天咱们来看看 go-zero 中的链路跟踪是如何利用的

别离从如下几个局部来看看 go-zero 中利用链路跟踪

  • Http 服务端局部,客户端局部

<!—->

  • Rpc 服务端局部,客户端局部

当然对于日志组件,数据库组件等相干组件,利用到链路跟踪的中央,做法大体一致,咱们一起看看 http 和 rpc 服务中利用的形式,其余的组件利用咱们也就能够简略的将常识迁徙过来即可上手

Http 服务端局部

对于 ge-zero http,咱们能够一起来看看 服务端局部是如何利用的

简略来说,在咱们启动 http 服务的时候,就曾经将链路追踪的性能给关上了,go-zero 是通过 http handle 的形式来解决的

当然,同理,咱们也能够本人在 go-zero 中加一个 middleware 也是能够达到这样的成果

go-zero 中实际上在咱们服务 start 的时候,外部就开始了各种初始化,大体流程是这样的

  • (s Server) Start() -> (ng engine) start(router httpx.Router) error

调用外部服务启动,注册路由

  • (ng engine) bindRoutes(router httpx.Router) -> (ng engine) bindFeaturedRoutes -> (ng *engine) bindRoute

进行路由的绑定,并默认增加中间件 middleware TracingHandler

咱们能够看看对于 TracingHandler 的源码实现

依据代码,咱们根本能够看进去 TracingHandler 次要做了这几件事件:

  1. 读取 HeaderCarrier,获取 header 中的上下文 ctx

<!—->

  1. 如果传入的 path 是空,则新建一个 spanName

<!—->

  1. tracer.Start 开始去解决 span,设置 span 的类型,属性

<!—->

  1. request 中产生新的 ctx,并将相应的信息封装在 ctx 中,返回

Rpc 服务端局部,客户端局部

那其实 rpc 服务端和客户端局部的实现和 http 的也是相似的,http 应用的是中间件的形式来进行解决,那么 rpc 这边块,其实能够通过拦截器的形式来进行解决

服务端

应用 go-zero 我的项目的框架,咱们在启动 rpc 服务的时候,看看都做了些什么

  • 服务 start,go-zero 默认就给咱们的 rpc 服务增加了一些默认的拦截器

    • 例如 UnaryTracingInterceptor
    • UnaryCrashInterceptor 等等

其中 UnaryTracingInterceptor 不难看出就是用于做拦路追踪的

而且咱们能够看到 rpc 局部的拦截器分为流式的和非流式的,例如用于链路追踪的还有 StreamTracingInterceptor

浏览服务端 UnaryTracingInterceptor 拦挡去源码,咱们能够晓得实际上做法和 http server 局部的做法大体一致

  • 通过 rpc 的 ctx 解决 span

<!—->

  • 设置 span 的状态和属性等键值对

<!—->

  • 返回具体服务接口的数据

客户端

那么客户端有什么不一样呢,其实也差不多

当咱们 api 层服务在初始化客户端的时候就会应用 zrpc 包的 MustNewClient 办法

跟踪代码咱们晓得,最终客户端的建设,会去和 rpc 服务端进行建设连贯,在建设连贯的过程中会带上一些参数

正式 buildDialOptions 在解决 options 的时候将客户端的拦截器给默认加上了 UnaryTracingInterceptorStreamTracingInterceptor

那么 UnaryTracingInterceptor 的具体实现是这个样的:

  • 获取上游带下来的 span 上下文信息,startspan 中解决了对于 span 数据结构中的各种键值对

<!—->

  • 从获取的 span 中创立新的 ctx,span「继承父 span 的 traceId」

<!—->

  • 将生成 span 的 data 退出 ctx,传递到下一个中间件,流至上游

对于 微服务框架 go-zero 的链路追踪简略的流程咱们就先走到这里,有趣味的也能够把他用起来

【欢送查看历史文章】

  • 微服务框架 go-zero logx 日志组件分析
  • 微服务框架 go-zero 疾速实战

感激浏览,欢送交换,点个赞,关注一波 再走吧

欢送点赞,关注,珍藏

敌人们,你的反对和激励,是我保持分享,提高质量的能源

好了,本次就到这里

技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。

我是 阿兵云原生,欢送点赞关注珍藏,下次见~

正文完
 0