共计 3975 个字符,预计需要花费 10 分钟才能阅读完成。
本片介绍 go micro 中应用 jaeger 作为链路追踪的应用
jaeger 相干常识请见官网文档,这里应用 docker 启动 gaeger,作为测试应用
启动 jaeger
docker run -d -p 6831:6831/udp -p 16686:16686 jaegertracing/all-in-one:latest
拜访地址 http://localhost:16686
go micro 版本 2.x,和 1.x 有些许不同
样例代码应用 examples/greeter 中代码批改 srv/mian.go
// Package main
package main
import (
"context"
"io"
"time"
hello "github.com/micro/examples/greeter/srv/proto/hello"
"github.com/micro/go-micro/v2"
"github.com/micro/go-micro/v2/util/log"
wrapperTrace "github.com/micro/go-plugins/wrapper/trace/opentracing/v2"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {log.Log("Received Say.Hello request")
rsp.Msg = "Hello" + req.Name
return nil
}
func main() {t, io, err := NewTracer("tracer-srv", "127.0.0.1:6831")
if err != nil {log.Fatal(err)
}
defer io.Close()
opentracing.SetGlobalTracer(t)
service := micro.NewService(micro.Name("go.micro.srv.greeter"),
micro.WrapHandler(wrapperTrace.NewHandlerWrapper(opentracing.GlobalTracer())),
)
// optionally setup command line usage
service.Init()
// Register Handlers
hello.RegisterSayHandler(service.Server(), new(Say))
// Run server
if err := service.Run(); err != nil {log.Fatal(err)
}
}
// NewTracer 创立一个 jaeger Tracer
func NewTracer(servicename string, addr string) (opentracing.Tracer, io.Closer, error) {
cfg := jaegercfg.Configuration{
ServiceName: servicename,
Sampler: &jaegercfg.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
BufferFlushInterval: 1 * time.Second,
},
}
sender, err := jaeger.NewUDPTransport(addr, 0)
if err != nil {return nil, nil, err}
reporter := jaeger.NewRemoteReporter(sender)
// Initialize tracer with a logger and a metrics factory
tracer, closer, err := cfg.NewTracer(jaegercfg.Reporter(reporter),
)
return tracer, closer, err
}
这里封装了 `NewTracer()` 创立一个 jaeger Tracer
在 main() 中 opentracing.SetGlobalTracer(t) 设置给 opentracing
micro 的 wrapper 有 4 种:
WrapHandler()
server 中间件WrapCall()
call 中间件WrapClient()
client 中间件WrapSubscriber()
订阅中间件
server 端咱们应用 micro.WrapHandler()
通过 micro plugins 自带的 opentracing 插件设置下
wrapperTrace.NewHandlerWrapper(opentracing.GlobalTracer())
cli/mian.go
package main
import (
"context"
"fmt"
"io"
"log"
"time"
hello "github.com/micro/examples/greeter/srv/proto/hello"
"github.com/micro/go-micro/v2"
wrapperTrace "github.com/micro/go-plugins/wrapper/trace/opentracing/v2"
"github.com/opentracing/opentracing-go"
"github.com/uber/jaeger-client-go"
jaegercfg "github.com/uber/jaeger-client-go/config"
)
func main() {t, io, err := NewTracer("tracer-cli", "127.0.0.1:6831")
if err != nil {log.Fatal(err)
}
defer io.Close()
opentracing.SetGlobalTracer(t)
// ctx, span, err := wrapperTrace.StartSpanFromContext(context.Background(), opentracing.GlobalTracer(), "root")
// create a new service
service := micro.NewService(micro.WrapClient(wrapperTrace.NewClientWrapper(opentracing.GlobalTracer())),
)
// parse command line flags
service.Init()
// Use the generated client stub
cl := hello.NewSayService("go.micro.srv.greeter", service.Client())
// Make request
rsp, err := cl.Hello(context.Background(), &hello.Request{Name: "John",})
if err != nil {fmt.Println(err)
return
}
fmt.Println(rsp.Msg)
}
// NewTracer 创立一个 jaeger Tracer
func NewTracer(servicename string, addr string) (opentracing.Tracer, io.Closer, error) {
cfg := jaegercfg.Configuration{
ServiceName: servicename,
Sampler: &jaegercfg.SamplerConfig{
Type: jaeger.SamplerTypeConst,
Param: 1,
},
Reporter: &jaegercfg.ReporterConfig{
LogSpans: true,
BufferFlushInterval: 1 * time.Second,
},
}
sender, err := jaeger.NewUDPTransport(addr, 0)
if err != nil {return nil, nil, err}
reporter := jaeger.NewRemoteReporter(sender)
// Initialize tracer with a logger and a metrics factory
tracer, closer, err := cfg.NewTracer(jaegercfg.Reporter(reporter),
)
return tracer, closer, err
}
client 端减少的代码和 server 基本一致,
只是 micro.NewService() 中应用的是中间件是 micro.WrapClient()
,
同时参数相应的变为 wrapperTrace.NewClientWrapper(opentracing.GlobalTracer())
运行起来
go run srv/main.go
go run cli/main.go
刷新 http://localhost:16686/ 即可看到
总结:
- go micro 在整个申请周期中都会带着 ctx,放入 header 中,详情请见【micro server 剖析】,链路追踪的原理就是在 header 中拿到追踪信息,存入剖析工具并解析,再展示到页面。
- 链路追踪不仅能够用于追踪整个申请周期,还可自定义追踪某几行代码,具体请见官网文档
参考【go-micro 实际】jaeger 分布式链路追踪