从 0 到 1 实现完整的微服务框架 - 链路追踪
在分布式系统,尤其是微服务系统中,一次外部请求往往需要内部多个模块,多个中间件,多台机器的相互调用才能完成。在这一系列的调用中,可能有些是串行的,而有些是并行的。在这种情况下,我们如何才能确定这整个请求调用了哪些应用?哪些模块?哪些节点?以及它们的先后顺序和各部分的性能如何呢?
这就是涉及到链路追踪。
jaeger 安装
|
|
api 层添加链路追踪
链路追踪的起点在每次发起 http 请求的地方,这时候就需要一个拦截器来生成 tracer
shop\api\user-api\middlewares\tracing.go
|
|
将这个中间件配置到需要链路追踪的 router 上
shop\api\user-api\initialize\router.go全局都加
|
|
由于我们使用了负载均衡,所以对于其他的 grpc 的链接要加一个拦截器,来将 context 加入到 grpc 服务中。
|
|
shop\api\user-api\util\otgrpc\client.go:31修改源码
|
|
这里修改源码是拿到 context 中的tracer和parentSpan
grpc 集成 jaeger
在服务端还有子的过程
client 拦截器的原理
从 context 拿到父亲的 span
|
|
通过 metadata 的机制,将它的内容写到 metadata 中去
|
|
然后通过shop\api\user-api\util\otgrpc\client.go:243
|
|
如何写到 opentracing 中去这是有一个标准,是由 opentracing 做的,如何提取也是由它来做的。
将服务端想要的信息注入到 metadata 中去,如果注入、拿数据我们不用关心。
在 grpc 服务端
|
|
只要在 new grpcserver 的时候添加一个服务端的拦截器就行
shop\service\user_srv\main.go
|
|
我们这边可以自己生成 tracer,没有必要用服务端的 tracer,我们只要处理好父子关系就好,当整个服务挂了之后 cl.Close()
在 grpc 的服务中如何拿到 tracer,
shop\service\user_srv\util\otgrpc\server.go:39从 context 中拿到 span
|
|
|
|
在服务中使用:
D:\repository\shop\service\user_srv\handler\user.go
|
|