本片介绍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 mainpackage mainimport ( "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 Tracerfunc 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 mainimport ( "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 Tracerfunc 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.gogo run cli/main.go
刷新http://localhost:16686/即可看到
总结:
- go micro 在整个申请周期中都会带着ctx,放入header中,详情请见【micro server剖析】,链路追踪的原理就是在header中拿到追踪信息,存入剖析工具并解析,再展示到页面。
- 链路追踪不仅能够用于追踪整个申请周期,还可自定义追踪某几行代码,具体请见官网文档
参考【go-micro实际】jaeger分布式链路追踪