使用opentelemetry-go操作Jaeger

最近工作上需要做性能优化需要对服务性能做监控,之前了解过一点分布式链路追踪,所以水篇文章。

可观察性入门

下面放一段opentelemetry的谷歌翻译,翻译不太好但是看个大概是可以的。

感兴趣可以看 opentelemetry的官网:

https://opentelemetry.io/

什么是可观察性?

可观察性让我们从外部了解一个系统,让我们在不知道其内部运作的情况下就该系统提出问题。此外,使我们能够轻松解决和处理新问题(即“未知的未知数”),并帮助我们回答“为什么会发生这种情况?”的问题。

为了能够询问系统的这些问题,必须对应用程序进行适当的检测。也就是说,应用程序代码必须发出 traces、 metrics和 logs等 signals。当开发人员不需要添加更多工具来解决问题时,应用程序会被正确地检测,因为他们拥有所需的所有信息。

OpenTelemetry是检测应用程序代码的机制,以帮助使系统可观察。

可靠性和指标

Telemetry(遥测) 是指从系统发出的关于其行为的数据。数据可以以Traces、 Metrics和Logs的形式出现。

Reliability(可靠性) 回答了这个问题:“服务是否在做用户期望它做的事情?” 一个系统可能 100% 的时间都在运行,但是如果当用户点击“添加到购物车”将一条黑色裤子添加到他们的购物车时,系统却不断添加一条红色裤子,那么系统会被说成是 可靠的。

Metrics(指标) 指标是一段时间内有关您的基础架构或应用程序的数字数据的聚合。示例包括:系统错误率、CPU 利用率、给定服务的请求率。

SLI或 Service Level Indicator,表示对服务行为的度量。一个好的 SLI 从用户的角度衡量您的服务。一个示例 SLI 可以是网页加载的速度。

SLO或服务水平目标是向组织/其他团队传达可靠性的方法。这是通过将一个或多个 SLI 附加到业务价值来实现的。

了解分布式跟踪

要了解分布式跟踪,让我们从一些基础知识开始。

Log

Log是由服务或其他组件发出的带时间戳的消息。然而,与Traces不同的是,它们不一定与任何特定的用户请求或事务相关联。它们几乎在软件中随处可见,过去开发人员和运营商都非常依赖它们来帮助他们理解系统行为。

样本日志:

I, [2021-02-23T13:26:23.505892 #22473]  INFO -- : [6459ffe1-ea53-4044-aaa3-bf902868f730] Started GET "/" for ::1 at 2021-02-23 13:26:23 -0800

不幸的是,日志对于跟踪代码执行并不是非常有用,因为它们通常缺少上下文信息,例如从哪里调用它们。

当它们作为Span的一部分包含时,它们变得更加有用。

Span

一个Span代表一个工作或操作单元。它跟踪请求进行的特定操作,描绘在执行该操作期间发生的事情。

Span 包含名称、时间相关数据、 结构化日志消息和 其他元数据(即属性),以提供有关它跟踪的操作的信息。

以下是 Span 中出现的信息类型示例:

有关 Spans 以及它们如何与 OTel 相关的更多信息,请访问 OpenTelemetry 中的 Spans。

分布式跟踪

分布式跟踪,通常称为跟踪,记录请求(由应用程序或最终用户发出)在通过多服务架构(如微服务和无服务器应用程序)传播时所采用的路径。

在没有跟踪的情况下,很难确定分布式系统中性能问题的原因。

它提高了我们应用程序或系统健康状况的可见性,并让我们能够调试难以在本地重现的行为。跟踪对于分布式系统至关重要,这些系统通常存在不确定性问题或过于复杂而无法在本地重现。

跟踪通过分解请求流经分布式系统时发生的情况,使调试和理解分布式系统变得不那么令人生畏。

Trace 由一个或多个 Span 组成。第一个 Span 代表 Root Span。每个 Root Span 代表一个从开始到结束的请求。父级下的 Span 提供了请求期间发生的更深入的上下文(或构成请求的步骤)。

许多可观察性后端将跟踪可视化为瀑布图,可能看起来像这样:

瀑布图显示了 Root Span 与其子 Span 之间的父子关系。当一个 Span 封装另一个 Span 时,这也代表了一种嵌套关系。

opentelemetry 简介

OpenTelemetry is a collection of tools, APIs, and SDKs. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.

OpenTelemetry 是工具、API 和 SDK 的集合。使用它来检测、生成、收集和导出遥测数据(指标、日志和跟踪),以帮助您分析软件的性能和行为。

Jaeger简介

Jaeger: open source, end-to-end distributed tracing

Jaeger:开源、端到端的分布式链路链路追踪框架。

Monitor and troubleshoot transactions in complex distributed systems

在复杂分布式系统中进行监控和故障排除

Jaeger 解决的问题

  • distributed transaction monitoring分布式事务监控
  • performance and latency optimization性能和延迟优化
  • root cause analysis根本原因分析
  • service dependency analysis服务依赖分析
  • distributed context propagation分布式上下文传播

感兴趣可以看看的官网

https://www.jaegertracing.io/

Jaeger服务docker部署

为了方便使用,部署采用官网的all-in-one的 镜像。

All-in-one is an executable designed for quick local testing, launches the Jaeger UI, collector, query, and agent, with an in memory storage component.

docker run -d --name jaeger \-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \-e COLLECTOR_OTLP_ENABLED=true \-p 6831:6831/udp \-p 6832:6832/udp \-p 5778:5778 \-p 16686:16686 \-p 4317:4317 \-p 4318:4318 \-p 14250:14250 \-p 14268:14268 \-p 14269:14269 \-p 9411:9411 \jaegertracing/all-in-one:1.35

执行命令后,打开http://127.0.0.1:16686/,出现下图则,安装成功

opentelemetry-go

opentelemetry-go 是go语言版本的客户端,使用opentelemetry-go 进行trace 上报十分简单。

官网如下:

https://github.com/open-telemetry/opentelemetry-go

官方举例:

package mainimport ("context""log""time""go.opentelemetry.io/otel""go.opentelemetry.io/otel/attribute""go.opentelemetry.io/otel/exporters/jaeger""go.opentelemetry.io/otel/sdk/resource"tracesdk "go.opentelemetry.io/otel/sdk/trace"semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
)const (service     = "trace-demo" // 服务名environment = "production" // 环境id          = 1      // id
)// 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.// tracerProvider 创建trace的提供者
func tracerProvider(url string) (*tracesdk.TracerProvider, error) {// Create the Jaeger exporter// 创建 Jaeger exporterexp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url)))if err != nil {return nil, err}tp := tracesdk.NewTracerProvider(// Always be sure to batch in production.tracesdk.WithBatcher(exp),// Record information about this application in a Resource.tracesdk.WithResource(resource.NewWithAttributes(semconv.SchemaURL,semconv.ServiceNameKey.String(service),attribute.String("environment", environment),attribute.Int64("ID", id),)),)return tp, nil
}func main() {tp, err := tracerProvider("http://localhost:14268/api/traces")if err != nil {log.Fatal(err)}// Register our TracerProvider as the global so any imported// instrumentation in the future will default to using it.// 设置全局的TracerProvider,方便后面使用otel.SetTracerProvider(tp)ctx, cancel := context.WithCancel(context.Background())defer cancel()// Cleanly shutdown and flush telemetry when the application exits.// 优雅退出defer func(ctx context.Context) {// Do not make the application hang when it is shutdown.ctx, cancel = context.WithTimeout(ctx, time.Second*5)defer cancel()if err := tp.Shutdown(ctx); err != nil {log.Fatal(err)}}(ctx)// trace 上报tr := tp.Tracer("component-main")ctx, span := tr.Start(ctx, "foo")defer span.End()// Context 向下传递bar(ctx)
}func bar(ctx context.Context) {// Use the global TracerProvider.// 使用 全局 TracerProvidertr := otel.Tracer("component-bar")_, span := tr.Start(ctx, "bar")span.SetAttributes(attribute.Key("testset").String("value"))defer span.End()// Do bar...
}

简单说明一下上报流程:

  1. 创建tracerProvider,通过tracerProvider来连接 Jaeger
  2. 创建Tracer ,推荐使用 全局的TracerProvider 来创建如:otel.Tracer("component-bar")
  3. 创建span ctx, span := tr.Start(ctx, "foo")
  4. 调用span.End(),完成上报。 defer span.End()

关键组件

TracerProvider 接口

// TracerProvider provides access to instrumentation Tracers.
//
// Warning: methods may be added to this interface in minor releases.
type TracerProvider interface {// Tracer creates an implementation of the Tracer interface.// The instrumentationName must be the name of the library providing// instrumentation. This name may be the same as the instrumented code// only if that code provides built-in instrumentation. If the// instrumentationName is empty, then a implementation defined default// name will be used instead.//// This method must be concurrency safe.Tracer(instrumentationName string, opts ...TracerOption) Tracer
}

可以简单理解为Tracer提供者,只有一个方法Tracer 返回tracer

Tracer 接口

// Tracer is the creator of Spans.
//
// Warning: methods may be added to this interface in minor releases.
type Tracer interface {// Start creates a span and a context.Context containing the newly-created span.//// If the context.Context provided in `ctx` contains a Span then the newly-created// Span will be a child of that span, otherwise it will be a root span. This behavior// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the// newly-created Span to be a root span even if `ctx` contains a Span.//// When creating a Span it is recommended to provide all known span attributes using// the `WithAttributes()` SpanOption as samplers will only have access to the// attributes provided when a Span is created.//// Any Span that is created MUST also be ended. This is the responsibility of the user.// Implementations of this API may leak memory or other resources if Spans are not ended.Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)
}

Tracer is the creator of Spans.Tracer是span的创造者,也只提供一个对象span

Span 接口

// Span is the individual component of a trace. It represents a single named
// and timed operation of a workflow that is traced. A Tracer is used to
// create a Span and it is then up to the operation the Span represents to
// properly end the Span when the operation itself ends.
//
// Warning: methods may be added to this interface in minor releases.
type Span interface {// End completes the Span. The Span is considered complete and ready to be// delivered through the rest of the telemetry pipeline after this method// is called. Therefore, updates to the Span are not allowed after this// method has been called.End(options ...SpanEndOption)// AddEvent adds an event with the provided name and options.AddEvent(name string, options ...EventOption)// IsRecording returns the recording state of the Span. It will return// true if the Span is active and events can be recorded.IsRecording() bool// RecordError will record err as an exception span event for this span. An// additional call to SetStatus is required if the Status of the Span should// be set to Error, as this method does not change the Span status. If this// span is not being recorded or err is nil then this method does nothing.RecordError(err error, options ...EventOption)// SpanContext returns the SpanContext of the Span. The returned SpanContext// is usable even after the End method has been called for the Span.SpanContext() SpanContext// SetStatus sets the status of the Span in the form of a code and a// description, overriding previous values set. The description is only// included in a status when the code is for an error.SetStatus(code codes.Code, description string)// SetName sets the Span name.SetName(name string)// SetAttributes sets kv as attributes of the Span. If a key from kv// already exists for an attribute of the Span it will be overwritten with// the value contained in kv.SetAttributes(kv ...attribute.KeyValue)// TracerProvider returns a TracerProvider that can be used to generate// additional Spans on the same telemetry pipeline as the current Span.TracerProvider() TracerProvider
}

Span is the individual component of a trace. It represents a single named and timed operation of a workflow that is traced. Span是trace的单个组成部分。 它代表了跟踪的工作流的单个命名和定时操作。

常用方法End:End completes the Span. The Span is considered complete and ready to be delivered through the rest of the telemetry pipeline after this method is called.完成span,此时Span被认为是完整的,已经准备好在此方法调用后通过剩下的 telemetry pipeline 传递。

简单理解下:调用end方法后,此时span是完整的,准备被上报。

更多opentelemetry-go操作其他分布式链路追踪组件可以看下方

https://github.com/open-telemetry/opentelemetry-go/tree/main/example

使用opentelemetry-go操作Jaeger相关推荐

  1. 一文教你如何在生产环境中在Kubernetes上部署Jaeger

    作者 |  Dotan Horovit 翻译 | 火火酱~ 责编 | 晋兆雨 出品 | CSDN云计算 日志.指标和跟踪是"可观察性"领域的三大支柱.最近几个月,随着OpenTel ...

  2. Cilium 1.11 发布,带来内核级服务网格、拓扑感知路由....

    作者:Cilium 母公司 Isovalent 团队 译者:范彬,狄卫华,米开朗基杨 注:本文已取得作者本人的翻译授权! 原文链接:https://isovalent.com/blog/post/20 ...

  3. 关于大型网站技术演进的思考

    关于大型网站技术演进的思考(一)--存储的瓶颈(1) 前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出 ...

  4. opentelemetry+python+jaeger链路追踪相关使用备注

    什么是链路追踪: 在 分布式微服务架构中, 一个请求从用户发起到接收,后端服务可能要经过多个微服务间调用,及多个功能组件(mysql,redis...)和网络请求(http,upd),在这个过程中,任 ...

  5. Jaeger插件开发及背后的思考

    简介: 本文主要介绍Jaeger最新的插件化后端的接口以及开发方法,让大家能够一步步的根据文章完成一个Jaeger插件的开发.此外SLS也推出了对于Jaeger的支持,欢迎大家试用. 随着云原生 + ...

  6. 【分布式系统篇】链路追踪之Jaeger安装使用入门

    目录 1. 前世 2. Jaeger与Zipkin 2.1 关于Jaeger 3. 安装 4. 使用 4.1 启动一个应用 4.2 发送请求 4.2 Jaeger查看服务架构 4.3 查看一个trac ...

  7. 现代应用参考架构之 OpenTelemetry 集成进展报告

    原文作者:Elijah Zupancic & Jason Schmidt of F5 原文链接:现代应用参考架构之 OpenTelemetry 集成进展报告 转载来源:NGINX 官方网站 去 ...

  8. 链路追踪之Jaeger安装与使用

    Jaeger 介绍: 官方给出的特性介绍: 分布式上下文传递 分布式事务监控 根本原因分析 服务依赖分析 性能.延迟优化 可扩展性 Jaeger的后端为无单点故障设计,可随时根据需要进行扩展:uber ...

  9. OpenTelemetry系列 (三)| 神秘的采集器 - Opentelemetry Collector

    前言 上个篇章中我们主要介绍了OpenTelemetry的客户端的一些数据生成方式,但是客户端的数据最终还是要发送到服务端来进行统一的采集整合,这样才能看到完整的调用链,metrics等信息.因此在这 ...

最新文章

  1. 如何用html制作心,html – 如何创建CSS心脏? /为什么这个CSS创造一个心脏的形状?...
  2. 利用node、express初始化项目
  3. python智能办公系统_用 Python 自动化办公能做到哪些有趣或有用的事情?
  4. c#Struts框架理念和自制Struts框架下 复杂版
  5. 编程方法学21:监听器和迭代器回顾
  6. Spring Security——基于读写锁的动态权限配置FilterInvocationSecurityMetadataSource实现类
  7. 二进制位交换,反转,与统计1的个数
  8. H面试程序(29):求最大递增数
  9. 使用 FieldMask 提高 C# gRpc 服务性能
  10. GOOGLE搜索出来的你的网站说明是乱码的
  11. python-运算符-比较运算符
  12. JNA参数传递问题,Java数组
  13. datetime类型怎么输入_数据库之mysql的基础类型
  14. CSS3混合模式mix-blend-mode/background-blend-mode简介 ,PS中叠加效果
  15. java keytool下载_JavaJDK自带工具keytool生成ssl证书
  16. python矩阵转置_矩阵转置python
  17. **使用InkScape绘制简易字母LOGO的教程**
  18. C语言计算排列组合C(m,n)的值
  19. 前段vue+后端接口PHP实现万年历(带上节假日天干地支凶吉星座神)
  20. 如何画好室内手绘效果图,非常值得…

热门文章

  1. SourceTree安装跳过注册
  2. JAVA通过Hutool解析CSV文件【导入即用,无需封装】
  3. 物流快递信息查询管理系统网站(JSP+HTML+MySQL)
  4. Code Review 有感
  5. Android 应用apk打包原理
  6. 数论--欧几里得和扩展的欧几里得定理
  7. Python进程池Pool的使用
  8. flask之人工智能
  9. 抱怨,是对自己无能的愤慨
  10. 【jquery】删除节点 添加节点 找兄弟节点