• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    golang 链路追踪的实现示例

    发布者: 琛瑞6678 | 发布时间: 2025-8-14 07:21| 查看数: 59| 评论数: 0|帖子模式

    分布式链路追踪(Distributed Tracing),也叫分布式链路跟踪,分布式跟踪,分布式追踪等等。

    问题

    场景1:调用链过长,查询很慢

    web-gin由A负责,服务A由B负责,某个接口出现异常了,先查询日志看是哪个地方出错了,发现服务A调用失败,依次找到D
    场景2:接口相应很慢


    解决方法

    (1)打日志:慢(可能不看懂其他人写的日志)
    (2)ELK:可以解决,也是日志需要写入
    (3)第三方链路追踪系统可以解决

    链路追踪系统技术选型

    java使用zipkin和skywalking比较多,而go使用jaeger多
    zipkinjaegerskywalkingOpenTracing是是是客户端支持语言java、c#、php、python等java、c#、go、php、python等java、.Net Core、NodeJS、PHP、python存储ES、Mysql、Cassandra内存ES、kafka、Cassandra内存ES、H2、mysql、TIDB、shard sphere传输协议支持http、MQudp/httpgRPCui丰富程度低中中实现方式-代码侵入式拦截请求,侵入拦截请求,侵入字节码注入,无侵入扩展性高高中trace查询支持支持支持性能损失中中低选择jaeger:官方支持jaeger技术选型原则:客户端支持、综合考虑、什么语言开发的
    安装jaeger
    1. docker run \
    2.   --rm \
    3.   --name jaeger \
    4.   -p6831:6831/udp \
    5.   -p16686:16686 \
    6.   jaegertracing/all-in-one:latest
    复制代码
    架构


    Jaeger组成
    1.Jaeger Client - 为不同语言实现了符合 OpenTracing 标准的 SDK。应用程序通过 API 写入数据,client library 把 trace 信息按照应用程序指定的采样策略传递给 jaeger-agent。
    2.Agent - 它是一个监听在 UDP 端口上接收 span 数据的网络守护进程,它会将数据批量发送给 collector。它被设计成一个基础组件,部署到所有的宿主机上。Agent 将 client library 和 collector 解耦,为 client library 屏蔽了路由和发现 collector 的细节。2.Collector - 接收 jaeger-agent 发送来的数据,然后将数据写入后端存储。Collector 被设计成无状态的组件,因此您可以同时运行任意数量的 jaeger-collector。
    3.Data Store - 后端存储被设计成一个可插拔的组件,支持将数据写入 cassandra、elastic search。
    4.Query - 接收查询请求,然后从后端存储系统中检索 trace 并通过 UI 进行展示。 Query 是无状态的,您可以启动多个实例,把它们部署在 nginx 这样的负载均衡器后面。
    分布式追踪系统发展很快,种类繁多,但核心步骤一般有三个:代码埋点,数据存储、查询展示订单调用过程


    添加jaeger
    1. sudo go get github.com/jaegertracing/jaeger-client-go
    复制代码
    发送span
    1. package main

    2. import (
    3.         "time"

    4.         "github.com/uber/jaeger-client-go"
    5.         jaegercfg "github.com/uber/jaeger-client-go/config"
    6. )

    7. func main() {
    8.         cfg := jaegercfg.Configuration{
    9.                 Sampler: &jaegercfg.SamplerConfig{
    10.                         Type:  jaeger.SamplerTypeConst,
    11.                         Param: 1, //[0,1] 0不采样1一直采样
    12.                 },
    13.                 Reporter: &jaegercfg.ReporterConfig{
    14.                         LogSpans:           true, //打不打印日志
    15.                         LocalAgentHostPort: "192.168.31.19:6831",
    16.                 },
    17.                 ServiceName: "shop",
    18.         }
    19.         tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
    20.         if err != nil {
    21.                 panic(err)
    22.         }
    23.         defer closer.Close()
    24.         span := tracer.StartSpan("go-grpc-web")
    25.         time.Sleep(time.Second)
    26.         defer span.Finish()
    27. }
    复制代码
    嵌套span
    1. package main

    2. import (
    3.         "time"

    4.         "github.com/opentracing/opentracing-go"
    5.         "github.com/uber/jaeger-client-go"
    6.         jaegercfg "github.com/uber/jaeger-client-go/config"
    7. )

    8. func main() {
    9.         cfg := jaegercfg.Configuration{
    10.                 Sampler: &jaegercfg.SamplerConfig{
    11.                         Type:  jaeger.SamplerTypeConst,
    12.                         Param: 1, //[0,1] 0不采样1一直采样
    13.                 },
    14.                 Reporter: &jaegercfg.ReporterConfig{
    15.                         LogSpans:           true, //打不打印日志
    16.                         LocalAgentHostPort: "39.103.59.35:6831",
    17.                 },
    18.                 ServiceName: "shop",
    19.         }
    20.         tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
    21.         if err != nil {
    22.                 panic(err)
    23.         }
    24.         defer closer.Close()
    25.         parentSpan := tracer.StartSpan("main")

    26.         spanA := tracer.StartSpan("funcA", opentracing.ChildOf(parentSpan.Context()))
    27.         time.Sleep(time.Millisecond * 500)
    28.         spanA.Finish()

    29.         spanB := tracer.StartSpan("funcB", opentracing.ChildOf(parentSpan.Context()))
    30.         time.Sleep(time.Millisecond * 1000)
    31.         spanB.Finish()

    32.         parentSpan.Finish()
    33. }
    复制代码
    grpc使用jaeger
    1. package main

    2. import (
    3.         "context"
    4.         "fmt"
    5.         "japter_test/proto"

    6.         "japter_test/otgrpc"

    7.         "github.com/opentracing/opentracing-go"
    8.         "github.com/uber/jaeger-client-go"
    9.         jaegercfg "github.com/uber/jaeger-client-go/config"
    10.         "google.golang.org/grpc"
    11. )

    12. func main() {
    13.         cfg := jaegercfg.Configuration{
    14.                 ServiceName: "mxshop",
    15.                 Sampler: &jaegercfg.SamplerConfig{
    16.                         Type:  jaeger.SamplerTypeConst,
    17.                         Param: 1, //[0,1] 0不采样1一直采样
    18.                 },
    19.                 Reporter: &jaegercfg.ReporterConfig{
    20.                         LogSpans:           true, //打不打印日志
    21.                         LocalAgentHostPort: "39.103.59.35:6831",
    22.                 },
    23.         }
    24.         tracer, closer, err := cfg.NewTracer(jaegercfg.Logger(jaeger.StdLogger))
    25.         if err != nil {
    26.                 panic(err)
    27.         }
    28.         opentracing.SetGlobalTracer(tracer)
    29.         defer closer.Close()

    30.         conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure(), grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(opentracing.GlobalTracer())))
    31.         if err != nil {
    32.                 panic(err)
    33.         }
    34.         defer conn.Close()
    35.         c := proto.NewGreeterClient(conn)
    36.         r, err := c.SayHello(context.Background(), &proto.HelloRquest{
    37.                 Name: "bobby",
    38.         })
    39.         if err != nil {
    40.                 panic(err)
    41.         }
    42.         fmt.Println(r.Message)
    43. }
    复制代码
    gin使用jaeger

    拦截器
    1. package middlewares

    2. import (
    3.         "GolangStudy/Practice/shop/goods-web/global"
    4.         "fmt"

    5.         "github.com/gin-gonic/gin"
    6.         "github.com/opentracing/opentracing-go"
    7.         "github.com/uber/jaeger-client-go"
    8.         jaegerConfig "github.com/uber/jaeger-client-go/config"
    9. )

    10. func Trace() gin.HandlerFunc {
    11.         return func(ctx *gin.Context) {
    12.                 cfg := jaegerConfig.Configuration{
    13.                         ServiceName: "your_service_name",
    14.                         Sampler: &jaegerConfig.SamplerConfig{
    15.                                 Type:  jaeger.SamplerTypeConst,
    16.                                 Param: 1, // 1 = always sample
    17.                         },
    18.                         Reporter: &jaegerConfig.ReporterConfig{
    19.                                 LogSpans:           true,
    20.                                 LocalAgentHostPort: fmt.Sprintf("%s:%d", global.ServerConfig.JaegerInfo.Host, global.ServerConfig.JaegerInfo.Port), // Jaeger Query 服务的地址和端口
    21.                         },
    22.                 }
    23.                 tracer, closer, err := cfg.NewTracer(jaegerConfig.Logger(jaeger.StdLogger))
    24.                 if err != nil {
    25.                         panic(err)
    26.                 }
    27.                 opentracing.SetGlobalTracer(tracer)
    28.                 defer closer.Close()
    29.                 startSpan := tracer.StartSpan(ctx.Request.URL.Path)
    30.                 defer startSpan.Finish()
    31.                 ctx.Set("tracer", tracer)
    32.                 ctx.Set("parentSpan", startSpan)
    33.                 ctx.Next()
    34.         }
    35. }
    复制代码
    使用
    1. GoodsRouter := Router.Group("goods").Use(middlewares.Trace())
    复制代码
    到此这篇关于golang 链路追踪的实现示例的文章就介绍到这了,更多相关golang 链路追踪内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表