共计 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 次要做了这几件事件:
- 读取 HeaderCarrier,获取 header 中的上下文 ctx
<!—->
- 如果传入的 path 是空,则新建一个 spanName
<!—->
- tracer.Start 开始去解决 span,设置 span 的类型,属性
<!—->
- 从
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 的时候将客户端的拦截器给默认加上了 UnaryTracingInterceptor 和 StreamTracingInterceptor
那么 UnaryTracingInterceptor 的具体实现是这个样的:
- 获取上游带下来的 span 上下文信息,startspan 中解决了对于 span 数据结构中的各种键值对
<!—->
- 从获取的 span 中创立新的 ctx,span「继承父 span 的 traceId」
<!—->
- 将生成 span 的 data 退出 ctx,传递到下一个中间件,流至上游
对于 微服务框架 go-zero 的链路追踪简略的流程咱们就先走到这里,有趣味的也能够把他用起来
【欢送查看历史文章】
- 微服务框架 go-zero logx 日志组件分析
- 微服务框架 go-zero 疾速实战
感激浏览,欢送交换,点个赞,关注一波 再走吧
欢送点赞,关注,珍藏
敌人们,你的反对和激励,是我保持分享,提高质量的能源
好了,本次就到这里
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是 阿兵云原生,欢送点赞关注珍藏,下次见~