前言

Opentelemetry

分布式链路跟踪( Distributed Tracing )的概念最早是由 Google 提出来的,发展至今技术已经比较成熟,也是有一些协议标准可以参考。目前在 Tracing技术这块比较有影响力的是两大开源技术框架:Netflix 公司开源的 OpenTracing 和 Google 开源的 OpenCensus。两大框架都拥有比较高的开发者群体。为形成统一的技术标准,两大框架最终磨合成立了 OpenTelemetry 项目,简称 otel。otel 有链路追踪和监控告警两大块,关于监控告警,可以查看另一篇文章:Go 监控告警入门 Opentelemetry

Jaeger

Jaeger\ˈyā-gər\ 是 Uber 开源的分布式追踪系统,是支持 OpenTelemetry 的系统之一,也是 CNCF 项目。

安装 Jaeger

Jaeger 为我们准备了 Docker 镜像,我们可以很容易的安装。

docker run --rm --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318

截至到 2024-04-18, Jaeger 的最新版本是 1.56。

简单的介绍以下这三个端口。16686 用做 Jaeger 服务的 Web 面板,一会我们可以在浏览器中访问它;4317 和 4318 都用做上传追踪数据,不同之处在于前者是 gRPC 协议,后者是 HTTP 协议。

Jaeger 还有很多可用的端口,本篇只介绍和 otel 相关的,具体可以查看 Jaeger 官方文档哦。

安装后,在浏览器中输入 IP:16686:

看到 gopher 侦探在追踪足迹的可爱图片就代表 Jaeger 安装成功咯。

编写 Go 代码

安装依赖:

go get "go.opentelemetry.io/otel" \
"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric" \
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace" \
"go.opentelemetry.io/otel/propagation" \
"go.opentelemetry.io/otel/sdk/metric" \
"go.opentelemetry.io/otel/sdk/resource" \
"go.opentelemetry.io/otel/sdk/trace" \
"go.opentelemetry.io/otel/semconv/v1.24.0" \
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"

我这里贴出 HTTP 和 gRPC 的全部代码,直接复制过去,改成自己的地址即可:

HTTP

func TestTraceHttp(t *testing.T) {
ctx := context.Background() // 创建 OTLP HTTP 导出器,连接到 Jaeger
exporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpointURL("http://srv.com:4318/v1/traces")) if err != nil {
log.Fatalf("创建导出器失败: %v", err)
} // 创建资源
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceNameKey.String("otel-traces-demo-http"),
),
)
if err != nil {
log.Fatalf("创建资源失败: %v", err)
} // 创建 Tracer 提供器
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
) // 设置全局 Tracer 提供器
otel.SetTracerProvider(tp) // 创建一个新的 trace
tracer := otel.Tracer("example-tracer")
ctx, span := tracer.Start(ctx, "root-span")
// 暂停 100ms
time.Sleep(100 * time.Millisecond)
// 结束 span
span.End() // 创建子span
_, childSpan := tracer.Start(ctx, "child-span")
// 暂停 50ms
time.Sleep(50 * time.Millisecond)
childSpan.End() // 确保所有的 spans 都被发送
if err := tp.Shutdown(ctx); err != nil {
log.Fatalf("关闭 Tracer 提供器失败: %v", err)
}
}

gRPC

func TestTraceGrpc(t *testing.T) {
ctx := context.Background() // 创建 OTLP gRPC 导出器,连接到 Jaeger
exporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint("srv.com:4317"),
otlptracegrpc.WithInsecure(),
) if err != nil {
log.Fatalf("创建导出器失败: %v", err)
} // 创建资源
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceNameKey.String("otel-traces-demo-grpc"),
),
)
if err != nil {
log.Fatalf("创建资源失败: %v", err)
} // 创建 Tracer 提供器
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(res),
) // 设置全局 Tracer 提供器
otel.SetTracerProvider(tp) // 创建一个新的 trace
tracer := otel.Tracer("example-tracer")
ctx, span := tracer.Start(ctx, "root-span")
// 暂停 100ms
time.Sleep(100 * time.Millisecond)
// 结束 span
span.End() // 创建子span
_, childSpan := tracer.Start(ctx, "child-span")
// 暂停 50ms
time.Sleep(50 * time.Millisecond)
childSpan.End() // 确保所有的 spans 都被发送
if err := tp.Shutdown(ctx); err != nil {
log.Fatalf("关闭 Tracer 提供器失败: %v", err)
}
}

效果

执行后,在面板中即可看到我们上传的数据。

可以看到我们的两个 span 已经上传到 Jaeger 中了,就是如此的简单!文中的代码开源在 Github

Go 链路追踪入门 Opentelemetry的更多相关文章

  1. 基于Dapper的分布式链路追踪入门——Opencensus+Zipkin+Jaeger

    微信搜索公众号 「程序员白泽」,进入白泽的编程知识分享星球 最近做了一些分布式链路追踪有关的东西,写篇文章来梳理一下思路,或许可以帮到想入门的同学.下面我将从原理到demo为大家一一进行讲解,欢迎评论 ...

  2. Jaeger Client Go 链路追踪|入门详解

    目录 从何说起 Jaeger 部署 Jaeger 从示例了解 Jaeger Client Go 了解 trace.span tracer 配置 Sampler 配置 Reporter 配置 分布式系统 ...

  3. Go微服务框架go-kratos实战05:分布式链路追踪 OpenTelemetry 使用

    一.分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(https://www. ...

  4. 基于 OpenTelemetry 的链路追踪

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

  5. spring cloud 入门系列八:使用spring cloud sleuth整合zipkin进行服务链路追踪

    好久没有写博客了,主要是最近有些忙,今天忙里偷闲来一篇. =======我是华丽的分割线========== 微服务架构是一种分布式架构,微服务系统按照业务划分服务单元,一个微服务往往会有很多个服务单 ...

  6. 分布式链路追踪体验-skywalking入门使用

    背景 旁友,你的线上服务是不是偶尔来个超时,或者突然抖动一下,造成用户一堆反馈投诉.然后你费了九牛二虎之力,查了一圈圈代码和日志才总算定位到问题原因了.或者公司内部有链路追踪系统,虽然可以很轻松地通过 ...

  7. 服务链路追踪(Spring Cloud Sleuth)

    sleuth:英 [slu:θ] 美 [sluθ] n.足迹,警犬,侦探vi.做侦探 微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元.由于服务单元数量众多,业务的 ...

  8. Spring Cloud 系列之 Sleuth 链路追踪(一)

    随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发.可能使用不同的编程语言来实现.有可能布在了 ...

  9. net core 微服务框架 Viper 调用链路追踪

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  10. 【开源】.net微服务开发引擎Anno 让复杂的事简单点- 日志、链路追踪一目了然 (上)

    1.Anno简介? Anno是一个微服务框架引擎.入门简单.安全.稳定.高可用.全平台可视化监控.依赖第三方框架少.详情请查看<[开源].net微服务开发引擎Anno开源啦> 本章主题:. ...

随机推荐

  1. Js 实现导航li列表,选中时,显示选中样式

    结合Django项目实现 实现步骤: html页面部分,使用bootstrap.css中的样式(不用可忽略,主要class样式),要引用bootstrap.css,使用到actvie样式: <l ...

  2. echo输出带颜色的字

    文章目录 格式 所有颜色 字体样式 示例 格式 \033[A;F;Bm #放在文本的左边,可以影响后面所有字体的样式 解释: F代表字体颜色值(Font),颜色编号30~37. B代表背景颜色值(Ba ...

  3. C# pythonnet(2)_傅里叶变换(FFT)

    Python代码如下 import pandas as pd import numpy as np import matplotlib.pyplot as plt # 读取数据 data = pd.r ...

  4. mysql子查询不支持limit问题解决

    如果sql语句中的子查询包含limit 例如: select * from table where id in (select id from table limit 3) 会报错: This ver ...

  5. 认识.NET 日志系统

    认识.NET 日志系统 基本概念 日志级别:Trace<Debug<Information<Waring<Error<Critical 日志提供者(LoggingProv ...

  6. 在Linux驱动中使用regmap

    背景 在学习SPI的时候,看到了某个rtc驱动中用到了regmap,在学习了对应的原理以后,也记录一下如何使用. 介绍 在Linu 3.1开始,Linux引入了regmap来统一管理内核的I2C, S ...

  7. ACPI Table 与 Device Tree

    背景 在分析Linux内核驱动的时候,有时候会看到一些acpi字样的接口. 之前一直没搞明白ACPI是什么,现在知道了. Reference : https://www.cnblogs.com/jun ...

  8. 【Hadoop】Hadoop集群组件默认端口

    这里包含使用到的组件:HDFS, YARN, HBase, Hive, ZooKeeper: 组件 节点 默认端口 配置 用途说明 HDFS DataNode 50010 dfs.datanode.a ...

  9. P7687 题解

    考场上数组开大了直接 MLE 了,气. 考虑把 A,B 两种服务分开算,一个边双连通分量内的点如过有一个有服务,那么整个联通分量就都有服务. 然后按边双联通分量缩点后原图变成树,一条边是关键路线当且仅 ...

  10. yb课堂 vue里面的状态管理vuex 《四十》

    文档:https://vuex.vuejs.org/zh/ 在store/下index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use ...