6 Ego Access 自定义链路

日志、链路、监控可以说是微服务治理的三驾马车,如下所示。 img_1.png

从图中,我们可以看到日志、链路、监控其实是有很多不一样的地方,同时又有一些交汇的地方。 我们将日志和链路的一些特性列一个表格。

方式采集类型量级优势调整采集格式
日志请求、错误、慢日志聚合、错误收敛调整日志级别动态
链路请求日志(可以细粒度到函数级别)traceId,调用关系调整采样率固定

链路记录的请求日志指标较多,同时可以细粒度到函数级别,最重要的是有全局唯一的trace id,能够串联各个系统的耗时、错误情况,但是他存在的最大问题是因为粒度较细,数据量巨大,只能采样,导致了有些数据可能缺失,同时他也不能聚合一些错误信息,做一些错误收敛。

而传统的框架请求日志,可以记录错误信息、错误收敛,但却没有链路的一些优秀特性。

我们可以看到日志和链路最大的共同点是都有记录请求日志,但他们的日志却无法共用,这就造成了极大的资源浪费,并且我们实际生产环境中并不需要链路细粒度到函数级别的,服务级别的链路通常就可以满足我们排查问题的需要。

所以我们在想,这两者是否能做个统一,让日志拥有聚合、错误收敛特性的同时,又能够有链路的一些优点。

在这里我们将Ego框架里的access日志改造成具有链路的特性,能够记录trace id串联各个服务,并且能够根据用户自定义的字段,记录uidorderId等信息。Ego框架如何实现日志、链路的统一,在这里我们可以用一个获取用户信息的例子来讲述下他的数据流向。

假设我们有两个服务,一个是HTTP a服务用于将用户信息数据吐给客户端,一个是gRPC b服务用于查询MySQL,将用户信息数据返给a服务。

  • 我们在ab服务启动前配置自定义的链路属性export EGO_LOG_EXTRA_KEYS=X-Ego-Uid,那么框架在读到这个环境变量里EGO_LOG_EXTRA_KEYS,会根据逗号分割,解析用户配置了多少个自定义的链路属性,后续的Ego组件会根据这个属性,自动将组件日志里追加这些用户自定义属性。
  • a服务接收到客户端的请求后,会根据token校验,校验通过后,在http.Request.Context()中写入X-Ego-Uid=9527的数据
  • 然后a服务,会将http.Request.Context()传入到gRPC客户端
  • gRPC客户端会取出gRPC context中的X-Ego-Uid=9527,并将其写入到gRPC header里,调用b服务
  • b服务接收到gRPC header中的X-Ego-Uid=9527,将其写入到Context里,传入到MySQL客户端
  • MySQL客户端从Context里获取到X-Ego-Uid=9527
  • 最后各个组件一次响应,并异步写入日志,在日志中追加trace-idx-ego-uid(链路id,框架已经内置,会自动追加,不需要用户配置)。

img.png

最终达到的效果,例如MySQLaccess日志中记录了uidtrace id信息。 img.png

以上就是Ego将日志中实现了链路的数据流向。快来体验吧。 如何传递和使用链路,请点击链接6 Ego Access 自定义链路 - 图4 (opens new window)

体验版本为:

  • github.com/gotomicro/ego@v0.6.2
  • github.com/gotomicro/ego-component/egorm@v0.2.2
  • github.com/gotomicro/ego-component/eredis@v0.2.3