go微服务框架Kratos笔记(六)链路追踪实战

什么是链路追踪

借用阿里云链路追踪文档来解释
分布式链路追踪(Distributed Tracing),也叫 分布式链路跟踪,分布式跟踪,分布式追踪 等等,它为分布式应用的开发者提供了完整的调用链路还原、调用请求量统计、链路拓扑、应用依赖分析等工具,可以帮助开发者快速分析和诊断分布式应用架构下的性能瓶颈,提高微服务时代下的开发诊断效率。
为了应对各种复杂的业务,开发工程师开始采用敏捷开发、持续集成等开发方式。系统架构也从单机大型软件演化成微服务架构。微服务构建在不同的软件集上,这些软件模块可能是由不同团队开发的,可能使用不同的编程语言来实现,还可能发布在多台服务器上。因此,如果一个服务出现问题,可能导致几十个应用都出现服务异常。

分布式追踪系统可以记录请求范围内的信息,例如一次远程方法调用的执行过程和耗时,是我们排查系统问题和系统性能的重要工具。

调用链

在广义上,一个调用链代表一个事务或者流程在(分布式)系统中的执行过程。在OpenTracing标准中,调用链是多个Span组成的一个有向无环图(Directed Acyclic Graph,简称DAG),每一个Span代表调用链中被命名并计时的连续性执行片段。
下图是一个分布式调用的例子:客户端发起请求,请求首先到达负载均衡器,接着经过认证服务、计费服务,然后请求资源,最后返回结果。
图 1. 分布式调用示例

go微服务框架Kratos笔记(六)链路追踪实战
数据被采集存储后,分布式追踪系统一般会选择使用包含时间轴的时序图来呈现这个调用链。

图 2. 包含时间轴的链路图

go微服务框架Kratos笔记(六)链路追踪实战

追踪信息

追踪信息包含时间戳、事件、方法名(Family+Title)、注释(TAG/Comment)。
客户端和服务器上的时间戳来自不同的主机,我们必须考虑到时间偏差,RPC 客户端发送一个请求之后,服务器端才能接收到,对于响应也是一样的(服务器先响应,然后客户端才能接收到这个响应)。这样一来,服务器端的 RPC 就有一个时间戳的一个上限和下限。

追踪采样

链路追踪在生成追踪和收集追踪数据的时候会消耗系统资源,在服务高负载情况下可能会导致系统性能下降,因为在链路追踪上可以参考跟踪采样的思路降低链路追踪的消耗。

  1. 固定采样(1/1024)
    这种采样方案对于高吞吐高负载的线上服务来说相当有用,在大吞吐量的情况下某些事件仍然可能经常出现,并且被采样到,但是在比较低的负载情况下这种采样方式往往可能会漏掉某些重要事件,而选择较高的采样率就需要接受性能损耗。
  2. 积极采样
    在低负载情况下固定采样无法采集到重要数据的情况下,可以采用动态的积极采样方式,例如在高QPS情况下采样率下降,低QPS下提高采样率。

如何使用

目前业界开源的知名链路追踪系统比如Google的Dapper,Twitter的zipkin,淘宝的鹰眼,新浪的Watchman,京东的Hydra等
而本文则使用Jaeger来作为链路追踪系统
简单用docker起一个jaeger
docker的安装

docker run -d -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778  -p 16686:16686 -p 14268:14268  -p 14269:14269   -p 9411:9411 jaegertracing/all-in-one:latest

访问127.0.0.1:16686
看到这个页面就OK了

go微服务框架Kratos笔记(六)链路追踪实战

在kratos中植入链路追踪

根据官方文档kratos 框架提供的自带中间件中有一个名为 tracing 中间件,它基于 Opentelemetry 实现了kratos 框架的链路追踪功能

  1. 在main.go中构建链路追踪
//构建全链路追踪
// tracerProvider returns an OpenTelemetry TracerProvider configured to use
// the Jaeger exporter that will send spans to the provided url. The returned
// TracerProvider will also use a Resource configured with all the information
// about the application.

func tracerProvider(url string) (*trace.TracerProvider, error) {
    // Create the Jaeger exporter
    exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
    if err != nil {
        return nil, err
    }
    tp := trace.NewTracerProvider(
        // Always be sure to batch in production.
        trace.WithBatcher(exp),
        // Record information about this application in an Resource.
        trace.WithResource(resource.NewWithAttributes(
            semconv.SchemaURL,
            semconv.ServiceNameKey.String(Name), //实例名称
            attribute.String("environment", Name), // 相关环境
            attribute.String("ID", Version),       //版本
        )),
    )
    return tp, nil
}
  1. 在main方法中调用tracerProvider
    //启动链路追踪,此处需要填写链路追踪采集地址
    //http://127.0.0.1:14268/api/traces
    tp, err := tracerProvider(config.GetConfig().GetString("jaeger.ipaddr"))
    if err != nil {
        panic(err)
    }
    //将tp作为全局链路追踪的提供程序
    otel.SetTracerProvider(tp)
  1. 在client和server端加上链路追踪中间件
    server端
//grpc
var opts = []grpc.ServerOption{
        grpc.Middleware(
            recovery.Recovery(),
            logging.Server(logger), //日志中间件
            tracing.Server(),       //链路追踪中间件
        ),
    }
//http
    var opts = []http.ServerOption{
        http.Middleware(
            recovery.Recovery(),
            logging.Server(logger), //日志中间件
            tracing.Server(),       //链路追踪中间件
        ),
    }

client端

    grpc.WithMiddleware(
            recovery.Recovery(),
            logging.Client(logger), //日志中间件,
            tracing.Client(),       //链路追踪中间件
        ),

启动server端和client端,访问一下接口
可以发现jaeger上成功监测到请求链路

go微服务框架Kratos笔记(六)链路追踪实战
拓扑图也成功展示出来
go微服务框架Kratos笔记(六)链路追踪实战

References

https://go-kratos.dev/blog/go-kratos-opentelemetry-practice
https://www.jianshu.com/p/07cf4093536a?from=singlemessage
https://help.aliyun.com/document_detail/90277.html?spm=5176.22294701.J_5253785160.4.49451088XuirYu
如有错误请留言反馈

Original: https://www.cnblogs.com/zly-go/p/15509235.html
Author: 悠悠听风
Title: go微服务框架Kratos笔记(六)链路追踪实战

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516534/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Go语言程序的命令行参数

    获取命令行参数是程序功能多样化的必要前提。 这个例子展示Go语言如何获得程序的命令行参数。 Go语言程序: // echoarg project main.go package m…

    Go语言 2023年5月29日
    050
  • Go内存逃逸分析

    Go的内存逃逸及逃逸分析 Go的内存逃逸 分析内存逃逸之前要搞清楚一件事 我们编写的程序中的 函数和 局部变量默认是存放在栈上的(补充一点堆上存储的数据的指针 是存放在栈上的 因为…

    Go语言 2023年5月25日
    047
  • GO后端开发+VUE实列

    因为我是从java转到go,代码结构跟我之前用java的很像 在这里只浅显的实战运用,没有过多理论讲解 工作环境:IDE:Goland , Go 1.17.7 框架 Gin+Gor…

    Go语言 2023年5月25日
    062
  • Go 语言快速开发入门

    需求 开发的步骤 linux下如何开发Go程序 MAC下如何开发Go程序 Golang执行流程分析 编译和运行说明 Go程序开发的注意事项 Go语言的转义字符(escapechar…

    Go语言 2023年5月25日
    078
  • 在开发中将git运用自如

    写这篇文章的初衷是记录自己在开发中使用git遇到的问题和如何利用git进行高效的开发。个人理解来看,很多人对git运用不自如主要是两方面的原因:1、死记硬背命令,这个其实可以通过h…

    Go语言 2023年5月25日
    050
  • EbitenCookBook中文教程 第一课:安装 Ebiten

    本文实时更新原址:https://ebitencookbook.vercel.app/docs/CookBook_Start/class1 第一课 安装 Ebiten 欢迎大家来到…

    Go语言 2023年5月25日
    061
  • Go语言 异常panic和恢复recover用法

    背景:Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会…

    Go语言 2023年5月29日
    053
  • GO语言常用时间工具类 timeUtil.go

    package util import “time” /*获取时间戳(纳秒)Testner 20210123/func GetTime_UnixNano()…

    Go语言 2023年5月29日
    074
  • DDIA 学习笔记

    第一章 可靠性、可扩展性、可维护性 ​ 可靠性: 系统在 困境(adversity)(硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准。 ​ 可靠…

    Go语言 2023年5月25日
    078
  • Go语言之网络编程

    一、网络编程基础 网络基础之TCP/IP协议族 网络编程之socket 二、TCP Socket编程 (一)流程 首先应该了解服务端和客户端的处理流程: 1、服务端处理流程 监听端…

    Go语言 2023年5月29日
    063
  • 基于Go语言实现好用的HTTP接口请求requests

    使用Go自带的net/http库可以发送各种HTTP请求。然而各种类型请求发送方式有点不太一致,这里参考Python requests库的使用方式,简单封装了一下。代码如下: 文件…

    Go语言 2023年5月29日
    061
  • Go语言实践模式 – 函数选项模式(Functional Options Pattern)

    什么是函数选项模式 大家好,我是小白,有点黑的那个白。 最近遇到一个问题,因为业务需求,需要对接三方平台. 而三方平台提供的一些HTTP(S)接口都有统一的密钥生成规则要求. 为此…

    Go语言 2023年5月25日
    046
  • Minio SDK访问Bucket的策略配置

    配置用户来访问 Bucket Minio 是高性能的对象存储服务,基于golang开发的,可以本地部署。用它来管理自己系统中的上传下载的文件很方便。​ 通过 SDK 访问 Mini…

    Go语言 2023年5月25日
    083
  • Excelize 2.5.0 正式发布,这些新增功能值得关注

    Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Mic…

    Go语言 2023年5月25日
    067
  • 记录解决安装 golang easyjson json包遇到的坑(有库但没有可执行文件)

    为什么要使用 easyjson 包: 因为解析json原生包用的是反射所以性能较差, 用 easyjson比原生json包快好几倍 安装: cmd 输入下载代码 go get -u…

    Go语言 2023年5月25日
    038
  • Go语言之函数

    函数就是一块执行特定任务的代码,在输入源的基础上通过一些算法生成预期的输出。 Go 语言中的函数声明语法如下: func 函数名(参数名 类型,参数名 类型)(返回值1类型,返回值…

    Go语言 2023年5月25日
    039
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球