微服务的可观测性大抵分为三大类:Metrics,Tracing 和 Logging。

Metrics 监控侧重于技术指标的收集与观测,如服务调用 QPS、响应工夫、错误率和资源使用率

Logging 侧重于运行日志的采集、存储与检索,通常应用ELK

Tracing 则偏差于调用链的串联、追踪与 APM 剖析,服务与服务之间的调用耗时等等,链路追踪。

一、对grpc服务进行监控
服务端

const (  serviceName        = "simple_zipkin_server"    zipkinAddr         = "http://127.0.0.1:9411/api/v1/spans"    zipkinRecorderAddr = "127.0.0.1:9000")/*    获取zipkin的tracer对象,并把tracer封装成ServerInterceptor注入到grpc.ServerOption中*/func NewZipkinTracer(opts []grpc.ServerOption) (opentracing.Tracer, []grpc.ServerOption, error) {    collector, err := zipkin.NewHTTPCollector(zipkinAddr)    if err != nil {        log.Fatal(err.Error())        return nil, opts, err    }    recorder := zipkin.NewRecorder(collector, true, zipkinRecorderAddr, serviceName)    tracer, err := zipkin.NewTracer(recorder, zipkin.ClientServerSameSpan(true), zipkin.TraceID128Bit(true))    if err != nil {        log.Fatal(err.Error())        return nil, opts, err    }    opts = append(opts, grpc_middleware.WithUnaryServerChain(        otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads()),    ))    return tracer, opts, nil}func main() {  //...  go func() {    //...    var opts = []grpc.ServerOption{grpc.Creds(cred)}        _, opts, err = NewZipkinTracer(opts)        if err != nil {            log.Fatal(err.Error())            return        }    rpcserver := grpc.NewServer(opts...)    //...  }  //...}

客户端

const (  serviceName        = "simple_zipkin_server"    zipkinAddr         = "http://127.0.0.1:9411/api/v1/spans"    zipkinRecorderAddr = "127.0.0.1:9000")/*    获取zipkin的tracer对象,并把tracer封装成ClientInterceptor注入到grpc.DialOption中*/func NewZipkinTracer(opts []grpc.DialOption) (opentracing.Tracer, []grpc.DialOption, error) {    collector, err := zipkin.NewHTTPCollector(zipkinAddr)    if err != nil {        log.Fatal(err.Error())        return nil, opts, err    }    recorder := zipkin.NewRecorder(collector, true, zipkinRecorderAddr, serviceName)    tracer, err := zipkin.NewTracer(recorder, zipkin.ClientServerSameSpan(true), zipkin.TraceID128Bit(true))    if err != nil {        log.Fatal(err.Error())        return nil, opts, err    }    opts = append(opts, grpc.WithUnaryInterceptor(        otgrpc.OpenTracingClientInterceptor(tracer, otgrpc.LogPayloads()),    ))    return tracer, opts, nil}func main() {  //...  var opts = []grpc.DialOption{grpc.WithTransportCredentials(creds)}    _, opts, err = NewZipkinTracer(opts)    if err != nil {        log.Fatal(err.Error())        return    }    conn, err := grpc.Dial(fmt.Sprintf("%v:%d", addr.Service.Address, addr.Service.Port), opts...)    if err != nil {        log.Fatal(err)    }    defer conn.Close()  //...}

先后运行server.go和client.go,进行一次grpc的调用;
拜访http://localhost:9411/zipkin,抉择"serviceName"为"simple_zipkin_server"

二、对Gin框架的Web服务进行监控

var (    zkReporter reporter.Reporter    zkTracer   opentracing.Tracer)const (    serviceName     = "zipkin_gin_server"    serviceEndpoint = "localhost:8080"    zipkinAddr      = "http://127.0.0.1:9411/api/v2/spans")func initZipkinTracer(engine *gin.Engine) error {    zkReporter = zkHttp.NewReporter(zipkinAddr)    endpoint, err := zipkin.NewEndpoint(serviceName, serviceEndpoint)    if err != nil {        log.Fatalf("unable to create local endpoint: %+v\n", err)        return err    }    nativeTracer, err := zipkin.NewTracer(zkReporter, zipkin.WithTraceID128Bit(true), zipkin.WithLocalEndpoint(endpoint))    if err != nil {        log.Fatalf("unable to create tracer: %+v\n", err)        return err    }    zkTracer = zkOt.Wrap(nativeTracer)    opentracing.SetGlobalTracer(zkTracer)  // 将tracer注入到gin的中间件中    engine.Use(func(c *gin.Context) {        span := zkTracer.StartSpan(c.FullPath())        defer span.Finish()        c.Next()    })    return nil}func main() {  engine := gin.Default()    err := initZipkinTracer(engine)    if err != nil {        panic(err)    }    defer zkReporter.Close()    engine.GET("/ping", func(c *gin.Context) {        c.JSON(http.StatusOK, "pong")    })   //...  engine.Run(":8080")}

参考文章:
https://blog.csdn.net/feizaoS...