文章首发公众号:海天二路搬砖工
引言
作为分布式跟踪系统的标准化API,OpenTracing提供了一种通用的方式来追踪和分析分布式系统中的请求和操作。
在Opentracing中,Span是基本的跟踪单元,用于描述在分布式系统中的一个操作或事件。通过收集和分析Span数据,我们可以更好地理解和优化分布式系统的性能和可靠性。
文中将深入探讨Opentracing中的Span,包括Span的定义、结构体、属性、操作、上下文等方面的内容。帮助读者更好地理解和应用Opentracing。
Span的简介
在OpenTracing中,跟踪数据通常由许多小的跨度(Span)组成 。 Span代表应用程序处理过程中的某个操作,例如 SQL 查询、HTTP 接口调用或函数调用等。每个Span都有一个开始时间和结束时间,并记录了其他元数据,例如跨度所属的节点、跨度的父子关系、错误信息和跨度的标签等。
Span的作用
Span作为分布式跟踪系统中的基本跟踪单元,具有以下作用:
- 追踪请求路径:在分布式系统中,一个请求通常会经过多个服务和组件,Span可以用于追踪请求在分布式系统中的路径。
- 监控系统状态:Span可以用于记录分布式系统中的事件和状态变化,例如服务调用、数据库查询、HTTP请求等。
- 分析性能指标:Span可以记录请求在分布式系统中的耗时和性能指标,例如响应时间、吞吐量、错误率等。
- 建立关联关系:Span可以用于建立Span之间的关联关系,例如父子关系、兄弟关系等,从而更好地理解和分析分布式系统中的请求和操作。
Tracer中的Span
Span是OpenTracing中具有开始时间和执行时长的逻辑运行单元。一条完整的追踪链可能包含多个span。 span之间通过嵌套或者顺序排列建立逻辑因果关系。
从继承维度看,一个Tracer的span一般如下图所示
从时间维度看,上面的Tracer的span的生命周期如下图所示
Span的基本属性
在OpenTracing中,Span对象具有以下几个基本属性:
- Operation Name(操作名称):指Span正在干什么的简短、描述性的名称。例如,"get_users"或"place_order"等。
- Start Time(开始时间)和Finish Time(完成时间):表示Span的开始和结束时间,用于确定Span的执行时间。Start Time和Finish Time以Unix时间戳形式存储。
- Duration(执行时间):Span执行所需的时间长度。Duraction可以通过Start Time和Finish Time计算得到。
- Parent Span ID(父Span ID)和Span ID(Span ID):分别表示Span在调用链路中的相对位置和唯一标识符。一个Span的Span ID是唯一的,而Parent Span ID则表示Span在调用链路中的父Span的Span ID。
- Tags(标签):可用于添加关于Span的元数据,例如Span所执行操作的请求方法、响应状态码、HTTP请求路径等。
- Logs(日志):可用于记录Span对象执行期间出现的某些动作和状态,例如某个操作的输入、输出等信息。
Span的上下文信息
在OpenTracing中,Span的上下文可以包括以下信息:
- Trace ID:表示跟踪的唯一标识符,重新启动或创建的一系列Span将共享该值。
- Parent Span ID:表示父Span的唯一标识符。
- Span ID:表示Span的唯一标识符。
通过Span的上下文,我们可以了解Span在调用链中的位置、关系以及它们之间传递的上下文数据,以便更好地了解操作执行过程和状态,并能够快速排除分布式系统中的性能和问题。
Span的结构体
在Opentracing中,Span通常被表示为一个结构体,包含了Span的各种元数据和属性。
Span的结构体在不同的语言和实现中可能会有所不同,但是大致的结构和属性应该是类似的。
type Span struct {
SpanContext SpanContext // Span的上下文信息,包括Trace ID、Span ID、Trace Flags等。
OperationName string // Span的名称,用于标识Span所代表的操作或事件。
StartTime time.Time // Span的开始时间。
Duration time.Duration // Span的持续时间。
Tags map[string]interface{} // Span的标签和附加信息等。
Logs []LogRecord // Span的日志和事件,用于记录Span上发生的事件和状态变化等。
References []SpanReference // Span的引用,用于建立Span之间的关联关系。
Tracer Tracer // 创建该Span的Tracer对象。
}
Span的常见操作
Span的开始和结束
Span可以分为两个阶段:开始()和结束()。我们可以调用start_span()函数创建一个新的Span,并使用finish()函数来标记Span的完成。Span的开始和结束对于我们跟踪分布式系统中的操作的执行时间和路径非常重要。
Span的日志和标记
在Span对象上添加日志和标记的功能是OpenTracing的一项重要特性。Span的标记通常是键值对,用于记录元数据。我们可以使用Span对象上的set_tag()方法来为Span添加标记。Span的日志通常是与Span所代表的事物的相关事件,例如记录SQL查询中的参数等。我们可以使用Span对象上的log()方法来记录关于Span的这些事件。
Span的嵌套和链接
有时,我们需要对操作进行更详细的跟踪。通过嵌套和链接Span对象,我们可以更好的跟踪分布式系统的操作执行路径。嵌套的Span表示一个操作的详细过程,其开始和结束都在外部Span开始和结束与之相关联。而Linked Span是一种用于表示两个Span对象之间的关系,例如父Span和子Span之间的关系。Linked Span可以通过在创建Span对象时引用旧的Span ID或创建一个新的Span ID来实现。
其他操作
-
设置Span的名称
Span的名称表示它正在记录的事件的名称和类型。我们在创建Span对象时可以指定Span的名称。
-
设置Span的时间戳
OpenTracing允许我们手动设置Span的开始和结束时间戳,以便记录分布式系统中的常见情况。
-
设置Span的上下文
我们可以使用Span对象上的set_()方法来设置Span对象的上下文,例如Span对象在哪个线程中执行。
总结
OpenTracing是一个用于在分布式系统中跟踪代码路径的工具。在OpenTracing中,Span是一个核心概念,代表分布式操作和服务调用的执行路径。Span的开始和结束、日志和标记、嵌套和链接是常见的Span操作,用于帮助我们更完整地记录Span对象的上下文,以便于进行应用程序的调试、排错和优化。Span的上下文信息、基本属性、结构体和常用操作等是掌握OpenTracing跟踪分布式系统的重要概念。