Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用
一、分布式链路追踪发展简介
1.1 分布式链路追踪介绍
关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(https://www.cnblogs.com/jiujuan/p/16097314.html) 。
这里的 OpenTelemetry 有一段发展历程。
APM(Application Performance Monitoring) 和 Distributed Tracing(分布式跟踪),后者是前者的子集。
微服务架构流行起来后,为了监控和定位微服务中请求链路过长导致的定位和监控问题,分布链路监控也蓬勃发展起来。出现了
很多有名的产品,比如:Jaeger,Pinpoint,Zipkin,Skywalking 等等。这里有个问题,就是每家都有自己的一套数据采集标准和SDK。
为了统一这些标准,国外的人们就创建了 OpenTracing 和 OpenCensus 2 个标准。最先出现的是 OpenTracing。为了统一标准,后来两者合并为 OpenTelemetry。
1.2 OpenTracing
OpenTracing 制定了一套与平台无关、厂商无关的协议标准,使得开发人员能够方便的添加或更换底层APM的实现。
它是 CNCF 的项目。OpenTracing 协议的产品有 Jaeger、Zipkin 等等。
OpenTracing 数据模型
- Trace(s):
Trace(s) 在 OpenTracing 中是被 spans 隐式定义的。一个 trace 可以被认为是由一个或多个 span 组成的有向无环图。
比如,下图示例就表示一个 trace 由 8 个 span 组成,也就是一次链路追踪由 8 个 span 组成:
单个 trace(链路) 中 span 之间的关系 [Span A] ←←←(the root span)
|
+------+------+
| |
[Span B] [Span C] ←←←(Span C is a `ChildOf` Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
↑
↑
↑
(Span G `FollowsFrom` Span F)
用时间轴来可视化这次链路追踪图,更容易理解:
Temporal relationships between Spans in a single Trace
––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
[Span A···················································]
[Span B··············································]
[Span D··········································]
[Span C········································]
[Span E·······] [Span F··] [Span G··] [Span H··]
(来自:https://opentracing.io/specification/)
- Span:
Span 是一次链路追踪里的基本组成元素,一个 Span 表示一个独立工作单元,比如一次 http 请求,一次函数调用等。每个 span 里元素:
- An operation name,服务/操作名称
- A start timestamp,开始时间
- A finish timestamp,结束时间
- Span Tags,key:value 数据形式,用户自定义的标签,主要用途是链路记录信息的查询过滤。
- Span Logs,key:value 数据形式,主要用途是记录某些事件和事件发生的时间。
- SpanContext 看下面解释
- References,对 0 或 更多个相关 span 的引用(通过 SpanContext 来引用)
- SpanContext:
SpanContext 携带跨进程(跨服务)通信的数据。它的组成:
- 在系统中表示 span 的信息。比如 span_id, trace_id。
- Baggage Items,为整条追踪链路保存跨进程(跨服务)的数据,数据形式是 key:value
- References
多个 span 中的对应关系。OpenTracing 目前定义了 2 种关系:
ChildOf和FollowsFrom:
ChildOf,一个子 span 可能是父 span 的 ChildOf[-Parent Span---------]
[-Child Span----] [-Parent Span--------------]
[-Child Span A----]
[-Child Span B----]
[-Child Span C----]
[-Child Span D---------------]
[-Child Span E----]
FollowsFrom,一些父 span 不依赖任何的子 span[-Parent Span-] [-Child Span-] [-Parent Span--]
[-Child Span-] [-Parent Span-]
[-Child Span-]
1.3 OpenCensus
为什么又出现个 OpenCensus 这个项目?因为它有个好爹:google。要知道分布式跟踪的基础论文就是谷歌提出。
其实,刚开始它并不是要抢 OpenTracing 的饭碗,它只是为了把 Go 语言的 Metrics 采集、链路跟踪与 Go 语言自带的
profile 工具打通,统一用户的使用方式。但是随着项目发展,它也想把链路相关的统一一下。它不仅要做 Metrics 基础指标监控,
还要做 OpenTracing 的老本行:分布式跟踪。
1.4 OpenTracing 与 OpenCensus 对比
2 者功能对比


1.5 OpenTelemetry
这样出现 2 个标准也不是个事啊,如是就出现了 OpenTelemetry,它把 2 者合并在一起了。
OpenTelemetry 的核心工作目前主要集中在 3 个部分:
- 规范的制定和协议的统一,规范包含数据传输、API 的规范,协议的统一包含:HTTP W3C 的标准支持及GRPC等框架的协议标准
- 多语言 SDK 的实现和集成,用户可以使用 SDK 进行代码自动注入和手动埋点,同时对其他三方库(Log4j、LogBack等)进行集成支持;
- 数据收集系统的实现,当前是基于 OpenCensus Service 的收集系统,包括 Agent 和 Collector。
(1.4 1.5来自: https://github.com/open-telemetry/docs-cn)
OpenTelemetry 的最终形态就是实现 Metrics、Tracing、Logging 的融合。
OpenTelemetry 整体架构图:

(来自:https://opentelemetry.io/docs/)
Tracing API 中几个重要概念:
- TracerProvider:是 API 的入口点,提供了对 tracer 的访问。在代码里主要是创建一个 Tracer,一般是第三方分布式链路管理软件提供具体实现。默认是一个空的 TracerProvider(""),虽然也创建 Tracer,但是内部不会执行数据流传输逻辑。
- Tracer:负责创建 span,一个 tracer 表示一次完整的追踪链路。tracer 由一个或多个 span 组成。跟上面的 OpenTracing 数据模型很像,所以说是两者合并。
- Span:一次链路追踪操作里的基本操作元素。比如一次函数调用,一次 http 请求。
里面还有很多详细介绍:https://opentelemetry.io/docs/reference/specification/trace/api/
还有一个数据采样,https://www.cnblogs.com/jiujuan/p/16097314.html - 前面学习 dapper 论文的这篇文章有介绍。
小结:
一条链路追踪信息:
有一条链路 trace,它是由一个或多个 span 组成, span 里会记录各种链路中的信息,跨进程的信息,各种 span 之间的关系。
使用哪种链路管理软件,则由 traceprovider 来设置。可以是 Jaeger,Pinpoint,Zipkin,Skywalking 等等。
span 中的信息收集到链路管理软件,然后可以用图来展示记录的链路信息和链路之间的关系。
二、jaeger 简介
Jaeger 是受到 Dapper 和 OpenZipkin 启发,是 Uber 开发的一款分布式链路追踪系统。
它用于监控微服务和排查微服务中出现的故障。
jaeger 架构图:

(来自:https://www.jaegertracing.io/docs/1.35/architecture/)
jaeger 安装:
参考我前面文章 :https://www.cnblogs.com/jiujuan/p/13235748.html docker all-in-one 安装
三、kratos 中链路追踪使用
前面介绍了那么多,应该对 opentelemetry 大致有了一个了解。下面就在 kratos 中使用 opentelemetry。
这里使用 jaeger 作为链路追踪的管理软件。
go 1.17
go-kratos 2.2.1
jaeger 1.35
下面代码来自 go-kratos 官方例子。
server 端
在 main.go 中,有 grpc server 和 http server。
第一步,设置 TraceProvider()
// set trace provider
func setTraceProvider(url string) error {
// create the jager exporter
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))
if err != nil {
return nil
}
// New trace provider
tp := tracesdk.NewTracerProvider(
// set the sampling rate based on the parent span to 100%, 设置采样率 100%
tracesdk.WithSampler(tracesdk.ParentBased(tracesdk.TraceIDRatioBased(1.0))),
// always be sure to batch in production
tracesdk.WithBatcher(exp),
// Record information about this application in an Resource.
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name), // service name
attribute.String("env", Env), // environment
attribute.String("version", Version), // version
)),
)
otel.SetTracerProvider(tp)
return nil
}
第二步,grpc server 和 http server
err := setTraceProvider(url) // 调用上面的 setTraceProvider 函数
if err != nil {
log.Error(err)
}
// grpc server
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
middleware.Chain(
recovery.Recovery(),
tracing.Server(), // 设置 trace
logging.Server(logger),
),
),
)
// http server
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
recovery.Recovery(),
tracing.Server(), // 设置 trace
logging.Server(logger),
),
)
client 端
grpc client 和 http client
grpc client:
// create grpc conn
// only for demo, use single instance in production env
conn, err := grpc.DialInsecure(ctx,
grpc.WithEndpoint("127.0.0.1:9000"),
grpc.WithMiddleware(
recovery.Recovery(),
tracing.Client(),
),
grpc.WithTimeout(2*time.Second),
// for tracing remote ip recording
grpc.WithOptions(grpcx.WithStatsHandler(&tracing.ClientHandler{})),
)
http client:
http.NewClient(ctx, http.WithMiddleware(
tracing.Client(
tracing.WithTracerProvider(s.tracer),
),
))
参考
- https://go-kratos.dev/docs/component/middleware/tracing/ 链路追踪
- https://go-kratos.dev/blog/go-kratos-opentelemetry-practice/ 基于OpenTelemetry的链路追踪
- https://opentracing.io/specification/ opentracing doc
- https://opentelemetry.io/docs/instrumentation opentelemetry doc
- https://opentelemetry.io/docs opentelemetry trace api
- https://opencensus.io/ opencensus 官网
- https://www.jaegertracing.io/docs/1.35/ jaeger doc
Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用的更多相关文章
- NET Core微服务之路:SkyWalking+SkyApm-dotnet分布式链路追踪系统的分享
对于普通系统或者服务来说,一般通过打日志来进行埋点,然后再通过elk或splunk进行定位及分析问题,更有甚者直接远程服务器,直接操作查看日志,那么,随着业务越来越复杂,企业应用也进入了分布式服务化的 ...
- Spring Boot + Spring Cloud 构建微服务系统(八):分布式链路追踪(Sleuth、Zipkin)
技术背景 在微服务架构中,随着业务发展,系统拆分导致系统调用链路愈发复杂,一个看似简单的前端请求可能最终需要调用很多次后端服务才能完成,那么当整个请求出现问题时,我们很难得知到底是哪个服务出了问题导致 ...
- 浅谈现公司的Spring Cloud微服务框架
目录 说在前面 服务注册与发现 服务网关及熔断 配置中心 消息中心.服务链路追踪 小言 说在前面 本文偏小白,大佬慎入,若有错误或者质疑,欢迎留言提问,谢谢,祝大家新年快乐. spring cloud ...
- NET Core微服务之路:实战SkyWalking+Exceptionless体验生产环境下的追踪系统
前言 当一个APM或一个日志中心实际部署在生产环境中时,是有点力不从心的. 比如如下场景分析的问题: 从APM上说,知道某个节点出现异常,或延迟过过高,却不能及时知道日志反馈情况,总不可能去相应的节点 ...
- NET Core微服务之路:实战SkyWalking+Exceptionless体验生产下追踪系统
原文:NET Core微服务之路:实战SkyWalking+Exceptionless体验生产下追踪系统 前言 当一个APM或一个日志中心实际部署在生产环境中时,是有点力不从心的. 比如如下场景分析的 ...
- go微服务框架Kratos笔记(六)链路追踪实战
什么是链路追踪 借用阿里云链路追踪文档来解释 分布式链路追踪(Distributed Tracing),也叫 分布式链路跟踪,分布式跟踪,分布式追踪 等等,它为分布式应用的开发者提供了完整的调用链路还 ...
- kratos微服务框架学习笔记一(kratos-demo)
目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服务框架学习笔记一(kratos-demo) 今年大部分时间飘过去了,没怎么更博和githu ...
- 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)...
原文:手把手0基础项目实战(一)--教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)... 本文你将学到什么? 本文将以原理+实战的方式,首先对& ...
- go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])
目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...
随机推荐
- 小程序生成海报demo
效果图: <view class='poste_box' id='canvas-container' style="margin:0 auto;border-radius:16rpx; ...
- 关于json对象的使用小结!
json是前后端数据交互的关键.后端提供的接口中的数据几乎都是通过json来表现的,所以,需要对这个json做一些小结: 这里要推进谷歌的插件Fehelp前端助手,这个可以清楚的看到json的数据: ...
- Python入门-面向对象三大特性-继承
面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容. 例如: 猫可以:喵喵叫.吃.喝.拉.撒 狗可以:汪汪叫.吃.喝.拉.撒 如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实 ...
- 微信小程序,制作属于自己的Icon图标
前言 最近在接手一个微信小程序,发现里面的图标都是使用的image组件,看起来非常别扭,加载也不太顺畅. 就想着看看微信有没有类似自带的图标库可以使用. 有是有,就是太少了,翻来翻去好像也就 8 种, ...
- Machine Learning 学习笔记 03 最小二乘法、极大似然法、交叉熵
损失函数. 最小二乘法. 极大似然估计. 复习一下对数. 交叉熵. 信息量. 系统熵的定义. KL散度
- 用Eclipse远程调试服务器tomcat
BEGIN; 在做远程调试时,在windows系统和非windows系统下的配置,Tomcat中会有所差别,具体如下: 第一步.配置tomcat 一.在windows系统中: 打开�TALINE_HO ...
- petite-vue源码剖析-沙箱模型
在解析v-if和v-for等指令时我们会看到通过evaluate执行指令值中的JavaScript表达式,而且能够读取当前作用域上的属性.而evaluate的实现如下: const evalCache ...
- 解决go-micro与其它gRPC框架之间的通信问题
在之前的文章中分别介绍了使用gRPC官方插件和go-micro插件开发gRPC应用程序的方式,都能正常走通.不过当两者混合使用的时候,互相访问就成了问题.比如使用go-micro插件生成的gRPC客户 ...
- 测试平台系列(92) 让http请求支持文件上传
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的教程,希望大家多多支持. 欢迎关注我的公众号米洛的测开日记,获取最新文章教程! 回顾 上一节呢,我们编写了oss的 ...
- [python][flask] Flask 入门(以一个博客后台为例)
目录 1.安装 1.1 创建虚拟环境 1.2 进入虚拟环境 1.3 安装 flask 2.上手 2.1 最小 Demo 2.2 基本知识 3.解构官网指导 Demo 3.1 克隆与代码架构分析 3.2 ...