本文介绍: 链路追踪(Distributed Tracing)是一种用于监测和诊断分布式应用程序请求路径技术。在分布式系统中,单个请求可能会涉及多个服务组件链路追踪通过记录分析请求在这些服务之间的传递路径执行情况,帮助开发人员运维团队理解系统运行状况、性能问题。Span(片段): 在链路追踪中,Span 是描述单个操作事件基本单元一个请求被分解成一个多个 Span,每个 Span 表示一个操作的开始和结束。例如,一个数据库查询一个 HTTP 请求、一个函数调用等都可以作为一个 Span。

为什么需要链路追踪

我们程序员日常工作中,最常做事情之一就是修bug了。如果程序只是运行在单机上,我们最常用的方式就是在程序上打日志然后程序运行过程中将日志输出文件上,然后我们根据日志推断程序是哪一步发生了问题。但是如果我们的程序部署分布式架构各个服务上,我们再用这种方法查看一个又一个日志文件,这就显得非常的低效了。所以这时候如果有一个可以帮助我们根据时间脉络将所有的信息都汇集起来并以可视化方式直观展示给我们看,我们的bugfix是不是就变得事半功倍了呢?

一、什么是链路追踪

链路追踪(Distributed Tracing)是一种用于监测和诊断分布式应用程序请求路径技术。在分布式系统中,单个请求可能会涉及多个服务组件。链路追踪通过记录分析请求在这些服务之间的传递路径执行情况,帮助开发人员和运维团队理解系统的运行状况、性能问题

二、链路追踪是怎么实现的?

1.链路追踪关键概念介绍

2.span是怎么基于context进行关联的?

由上面的概念我们大概可以想象到,一条追踪链路其实是由多个span组成的,而span之间是基于每一个span的context进行关联 (即根据context里的同一个trace id进行关联)

在这里插入图片描述

三、OpenTelemetry、Jaeger这些和链路追踪有什么关系?

四、怎么快速使用OpenTelemetry、Jaeger实现一个链路追踪的demo

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	
	"go.opentelemetry.io/otel"
	`go.opentelemetry.io/otel/attribute`
	"go.opentelemetry.io/otel/exporters/trace/jaeger"
	`go.opentelemetry.io/otel/sdk/resource`
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	`go.opentelemetry.io/otel/semconv`
	
	svc `otel/demo1/svc`
)

// 初始化 OpenTelemetry
func initTracer() *sdktrace.TracerProvider {
	exporter, err := jaeger.NewRawExporter(
		jaeger.WithAgentEndpoint(func(options *jaeger.AgentEndpointOptions) {
			options.Host = "localhost"
			options.Port = "6831"
		}),
	)
	if err != nil {
		log.Fatalf("Error creating Jaeger exporter: %v", err)
	}
	
	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
		sdktrace.WithSampler(sdktrace.AlwaysSample()),
		sdktrace.WithResource(resource.NewWithAttributes(
			semconv.ServiceNameKey.String("demo_service"), // 服务
		)),
	)
	otel.SetTracerProvider(tp)
	return tp
}

func main() {
	tp := initTracer()
	defer func() {
		if cerr := tp.Shutdown(context.Background()); cerr != nil {
			log.Fatalf("Error shutting down tracer provider: %v", cerr)
		}
	}()
	
	//启动http服务器
	http.HandleFunc("/demo", handleRequest)
	
	go func() {
		if err := http.ListenAndServe(":8080", nil); err != nil {
			log.Fatalf("Error starting Service A server: %v", err)
		}
	}()
	
	//模拟请求
	SimulateRequest()
}

func handleRequest(w http.ResponseWriter, req *http.Request) {
	tracer := otel.Tracer("root")
	//开始创建root span
	ctx, span := tracer.Start(req.Context(), "span root")
	defer span.End()
	
	//可以在span上记录一些信息,例如日志、请求参数sql语句
	span.SetAttributes(
		attribute.String("some root service info", "This is the root service"),
	)
	
	//访问服务A
	svc.CallServiceA(ctx)
	
	//访问服务B
	svc.CallServiceB(ctx)
	
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "Response from Service Root")
}

func SimulateRequest()  {
	req, err := http.NewRequest("GET", "http://localhost:8080/demo", nil)
	if err != nil {
		log.Fatalf("Creating request fail: %v", err)
	}
	
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Request failed: %v", err)
	}
	defer resp.Body.Close()
	fmt.Println("Response received from Root Service")
}

运行后打开http://localhost:16686,选择对应service查找trace可以看到
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

五、总结

  1. 链路追踪是依靠于一个随机生成的trace_id一条链路对应唯一一个trace_id
  2. Span 是描述单个操作或事件基本单元。一个请求被分解成一个或多个 Span。即一条链路是由多个span组成的。
  3. 在链路追踪中,context(上下文)是指跨越不同服务的信息传递。每个 Span 都关联一个上下文。
  4. OpenTelemetry 是一个用于跟踪和监控分布式系统的开放式标准和工具集。提供了一套标准的API 和工具,用于生成导出聚合跟踪数据,并将这些数据发送到各种后端。
  5. Jaeger、Zipkin、Prometheus等这些可以接收OpenTelemetry发送过来的数据,可以提供可视化的展示和分析数据的能力。

原文地址:https://blog.csdn.net/huanyi5214/article/details/134552886

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_17447.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注