前世今生
OpenTracing#
OpenTracing 项目启动于 2016 年,旨在提供一套分布式追踪标准,以便开发人员可以更轻松地实现分布式追踪。
OpenTracing 定义了一套 Tracing 模型,以及一套 API,用于在应用程序中创建和管理这些数据模型。
下面是 OpenTracing 的三种相互关联的核心模型:
Span
:表示一次调用过程,包括调用的起始和结束,以及调用过程中的一些信息,比如调用的服务名称、调用的方法名称、调用的参数、调用的返回值、调用的异常等。Tracer
:表示一个追踪器,用于创建和管理Span
,并将Span
发送到追踪系统。SpanContext
:表示Span
的上下文,包括TraceId
、SpanId
、Baggage
等信息。
OpenTracing 规定了 Span
上会包含以下信息:
- Operation Name:操作名称,表示
Span
所代表的操作的名称。 - Start Time:开始时间,表示
Span
的开始时间。 - Finish Time:结束时间,表示
Span
的结束时间。 - Tags:标签,表示
Span
的一些标签信息,比如http.method
、http.url
、http.status_code
等。 - Logs:日志,表示
Span
的一些日志信息,比如error
、exception
等。 - SpanContext:
Span
的上下文,包括TraceId
、SpanId
、Baggage
等信息。
Baggage
是 OpenTracing 中的一个概念,跨进程的 Span
之间可以通过 Baggage
传递一些用户自定义的数据,比如用户的 userId
、orderId
等。
OpenTracing 还定义了 SpanContext
跨进程传递相关的概念:
Tracer 通过 Inject
和 Extract
方法,将 SpanContext
信息注入到 Carrier
中,以便在跨进程的 Span
之间传递。
- Inject:将
SpanContext
信息注入到Carrier
中,以便在跨进程的Span
之间传递。 - Extract:从
Carrier
中提取SpanContext
信息,以便在跨进程的Span
之间传递。 - Carrier:载体,表示
SpanContext
信息的载体,比如 HTTP Header、RPC Header 等。
更多完整的 OpenTracing 规范,可以参考 OpenTracing Specification https://opentracing.io/specification/ 。
OpenTracing 还提供了一套 SDK用来实现 OpenTracing 规范,https://github.com/opentracing 。
这套 SDK 只包含数据模型和 API,不包含往后端追踪系统发送数据等功能,需要进一步集成后端追踪系统的 SDK,才能将数据发送到后端追踪系统。
例如,如果要将 Span
发送到 Jaeger,需要进一步集成 Jaeger 的 SDK,将 Span
发送到 Jaeger。
https://github.com/jaegertracing/jaeger-client-csharp/tree/master
OpenCensus#
OpenCensus 是 Google 于 2018年 组织的一个开源项目,相较于 OpenTracing 项目只支持 Tracing,OpenCensus 项目同时支持 Tracing 和 Metrics。
OpenTelemetry#
OpenTelemetry 是 OpenCensus 和 OpenTracing 项目的合并,于 2019年 由 CNCF 组织的一个开源项目。除了支持 Tracing 和 Metrics,还支持 Logging。
OpenTelemetry 的 Tracing 模型很大程度上继承了 OpenTracing 的 Tracing 模型,所以了解 OpenTracing 的 Tracing 模型,有助于理解 OpenTelemetry 的 Tracing 模型。
OpenTelemetry 项目介绍
OpenTelemetry 简称 OTel,包含三部分:
- OpenTelemetry Specification:OpenTelemetry 规范,定义了 OTel 的数据模型和 API,还包括标准的数据传输协议 OpenTelemetry Protocol,简称 OTLP。
- OpenTelemetry SDK:OpenTelemetry SDK,用于实现 OpenTelemetry 规范。
- OpenTelemetry Collector:一个可插拔的数据收集器,用于收集、处理、导出 OTel 的数据。
OpenTelemetry Specification#
OpenTelemetry Specification 定义了跨语言的规范,所有语言的 SDK 都需要遵循这个规范。
规范包括以下几个部分:
- API Specification:API 规范,规定了 OTel 的 API 应该包含哪些方法。
- SDK Specification:SDK 规范,规定了 OTel 的 SDK 应该应该提供哪些功能。
- Data Specification:数据规范,定义了 OTel 的数据模型。
详细的规范可以参考 https://opentelemetry.io/docs/specs/otel/
Signals#
OpenTelemetry Specification 定义了以下数据模型,这些模型统称为 Signals。
- Tracing
- Metrics
- Logs
- Baggage
上文 OpenTracing 的设计中都有这些概念,这边不再赘述。
Context & Propagation#
Context,表示一次调用过程中的上下文,用于在调用过程中传递一些数据,比如 Tracing、Baggage 等。
Propagators(传播器) 利用 Context 为每个横切关注点(例如 Tracing 和 Baggage)注入和提取数据。
通常,Context 会通过 HTTP Header、RPC Header 等方式传递。Propagators 会将 Context 中的数据注入到 HTTP Header、RPC Header 等中,以便在跨进程的调用过程中传递。
OpenTelemetry Protocol#
OpenTelemetry Protocol,简称 OTLP,是 OTel 定义的标准的数据传输协议,用于在 OTel 的 SDK 和可观测性后端之间传输数据。
https://opentelemetry.io/docs/specs/otlp/
OTLP 使用 gRPC 作为传输协议,各个可观测性后端只需要实现 OTLP 的 gRPC 接口,就可以接收 OTel 的数据。
在此之前,各个可观测性后端都有自己的数据传输协议,比如 Jaeger 使用的是 Jaeger Thrift Protocol,Zipkin 使用的是 Zipkin JSON V2 API 等。
OpenTelemetry SDK#
OpenTelemetry SDK架构#
虚线的上方是 OpenTelemetry API 的定义,下面是具体的 SDK 实现。
Tracing、Metrics、Logging 等数据收集被称为 Instrumentation,中文资料中通常叫做埋点。
除了 Instrumentation,还有 Sampler、Processor、Exporter 等组件。
- Sampler:采样器,用于决定数据的采样规则。
- Processor:处理器,用于处理数据,比如将数据聚合、压缩等。
- Exporter:导出器,用于将数据导出到可观测性后端。通过实现不同的 Exporter,可以将数据导出到不同的后端系统,比如 Jaeger、Zipkin、Prometheus 等。当然也可以通过 OTLP 标准协议将数据导出支持 OTLP 的后端系统。
OpenTelemetry Collector#
Collector 是一个独立的进程,用于收集、处理、导出 OTel 的数据。
Collector 主要由三个组件组成:
- Receiver:接收器,用于接收 OTel 的数据,支持多种数据格式,比如 OTLP、Jaeger Thrift、Zipkin JSON V2 API 等。
- Processor:处理器,用于处理数据,比如将数据聚合、压缩等。
- Exporter:导出器,用于将数据导出到可观测性后端。
Processor 和 Exporter 功能与 OpenTelemetry SDK 中的 Processor 和 Exporter 功能类似,但是 Collector 作为独立的进程,可以集中处理多个应用程序的数据(如通过 OTLP 的 Receiver 进行统一的收集),而不需要在每个应用程序中都集成 Processor 和 Exporter。
Collector 也是一个可插拔的架构,可以通过配置文件的方式,配置不同的 Processor、Exporter 等组件。
下期预告
下期开始将正式开始介绍如何在 .NET 应用中使用 OpenTelemetry,并在使用过程中,进一步介绍 OpenTelemetry 的设计和实现。