基于 OpenTelemetry 的链路追踪

链路追踪的前世今生

分布式跟踪(也称为分布式请求跟踪)是一种用于分析和监控应用程序的方法,尤其是使用微服务架构构建的应用程序。分布式跟踪有助于精确定位故障发生的位置以及导致性能差的原因。

起源

链路追踪(Distributed Tracing) 一词最早出现于谷歌发布的论文 《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》 中,这篇论文对于实现链路追踪,对于后来出现的 Jaeger、Zipkin 等开源分布式追踪项目设计理念仍有很深的影响。

微服务架构是一个分布式的架构,会有很多个不同的服务。不同的服务之前相互调用,如果出现了错误由于一个请求经过了 N 个服务。随着业务的增加越来越多的服务之间的调用,如果没有一个工具去记录调用链,解决问题的时候就会像下面图片里小猫咪玩的毛线球一样,毫无头绪,无从下手

所以需要有一个工具能够清楚的了解一个请求经过了哪些服务,顺序是如何,从而能够轻易的定位问题。

百家争艳

从谷歌发布 Dapper 后,分布式链路追踪工具越来越多,以下简单列举了一些常用的链路追踪系统

  • Skywalking
  • 阿里 鹰眼
  • 大众点评 CAT
  • Twitter Zipkin
  • Naver pinpoint
  • Uber Jaeger

争锋相对?

随着链路追踪工具越来越多,开源领域主要分为两派,一派是以 CNCF技术委员 会为主的 OpenTracing 的规范,例如 jaeger zipkin 都是遵循了OpenTracing 的规范。而另一派则是谷歌作为发起者的 OpenCensus,而且谷歌本身还是最早提出链路追踪概念的公司,后期连微软也加入了 OpenCensus

OpenTelemetry 诞生

OpenTelemetric 是一组 API、SDK、模组和集成,专为创建和管理‎‎遥测数据‎‎(如追踪、指标和日志)而设

微软加入 OpenCensus 后,直接打破了之前平衡的局面,间接的导致了 OpenTelemetry 的诞生
谷歌和微软下定决心结束江湖之乱,首要的问题是如何整合两个两个社区已有的项目,OpenTelemetry 主要的理念就是,兼容 OpenCensusOpenTracing ,可以让使用者无需改动或者很小的改动就可以接入 OpenTelemetry

Kratos 的链路追踪实践

Kratos 一套轻量级 Go 微服务框架,包含大量微服务相关框架及工具。

tracing 中间件

kratos 框架提供的自带中间件中有一个名为 tracing 中间件,它基于 Opentelemetry 实现了kratos 框架的链路追踪功能,中间件的代码可以从 middleware/tracing 中看到。

实现原理

kratos 的链路追踪中间件由三个文件组成 carrie.go,tracer.go,tracing.go。client和 server 的实现原理基本相同,本文以 server 实现进行原理解析。

  1. 首先当请求进入时,tracing 中间件会被调用,首先调用了 tracer.go 中的 NewTracer 方法
// Server returns a new server middleware for OpenTelemetry.
func Server(opts ...Option) middleware.Middleware {
   
   
        // 调用 tracer.go 中的 NewTracer 传入了一个 SpanKindServer 和配置项
	tracer := NewTracer(trace.SpanKindServer, opts...)
        // ... 省略代码
}
  1. tracer.go 中的 NewTracer 方法被调用后会返回一个 Tracer,实现如下
func NewTracer(kind trace.SpanKind, opts ...Option) *Tracer {
   
   
	options := options{
   
   }
	for _, o := range opts {
   
   
		o(&options)
	}
	// 判断是否存在 otel 追踪提供者配置,如果存在则设置
	if options.TracerProvider != nil {
   
   
		otel.SetTracerProvider(options.TracerProvider)
	}
	/*
	判断是否存在 Propagators 设置,如果存在设置则覆盖,不存在则设置一个默认的TextMapPropagator
	注意如果没有设置默认的TextMapPropagator,链路信息则无法正确的传递
	*/
	if options.Propagators != nil {
   
   
		otel.SetTextMapPropagator(options.Propagators)
	} else {
   
   	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.Baggage{
   
   }, propagation.TraceContext{
   
   }))
	}


	var name string
	// 判断当前中间件的类型,是 server 还是 client
	if kind == trace.SpanKindServer {
   
   
		name = "server"
	} else if kind == trace.SpanKindClient {
   
   
		name = "client"
	} else {
   
   
		panic(fmt.Sprintf("unsupported span kind: %v", kind))
	}
	// 调用 otel包的 Tracer 方法 传入 name 用来创建一个 tracer 实例
	tracer := otel.Tracer(name)
	return &Tracer
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值