jaeger详细使用说明(全网最全面和深入)

1、介绍

在微服务为我们提供了模块分,低耦合的高效开发和DevOPS中,具体业务中当一个请求中,请求了多个服务单元,如果请求出现了错误或异常,很难去定位是哪个服务出了问题,这时就需要链路追踪。可能你会想在业务系统中请求中埋点,或写日志,但是这种都需要在业务代码中来写,而且耦合在代码中,不具备微服务的扩张性后后期的易维护行。

1.1、Jaeger概念

受Dapper和OpenZipkin启发的Jaeger是由Uber Technologies作为开源发布的分布式跟踪系统。它用于监视和诊断基于微服务的分布式系统,包括:

分布式上下文传播

分布式交易监控

根本原因分析

服务依赖性分析性能/延迟优化

1.2、特性

1.2.1、高扩展性

Jaeger后端的设计没有单点故障,可以根据业务需求进行扩展。例如,Uber上任何给定的Jaeger安装通常每天要处理数十亿个跨度。

1.2.2、原生支持OpenTracing

Jaeger后端,Web UI和工具库已完全设计为支持OpenTracing标准。

通过跨度引用将迹线表示为有向无环图(不仅是树)

支持强类型的跨度标签和结构化日志通过行李

支持通用的分布式上下文传播机制

1.2.3、多存储后端

Jaeger支持两个流行的开源NoSQL数据库作为跟踪存储后端:Cassandra 3.4+和Elasticsearch 5.x / 6.x / 7.x。正在进行使用其他数据库的社区实验,例如ScyllaDB,InfluxDB,Amazon DynamoDB。Jaeger还附带了一个简单的内存存储区,用于测试设置。

1.2.4、现代化的UI

Jaeger Web UI是使用流行的开源框架(如React)以Javascript实现的。v1.0中发布了几项性能改进,以允许UI有效处理大量数据,并显示具有成千上万个跨度的跟踪(例如,我们尝试了具有80,000个跨度的跟踪)。

1.2.5、云原生部署

Jaeger后端作为Docker映像的集合进行分发。这些二进制文件支持各种配置方法,包括命令行选项,环境变量和多种格式(yaml,toml等)的配置文件。Kubernetes模板和Helm图表有助于将其部署到Kubernetes集群。

1.2.6、可观察

默认情况下,所有Jaeger后端组件都公开Prometheus指标(也支持其他指标后端)。使用结构化日志库zap将日志写到标准输出。

1.2.7、安全

Jaeger的第三方安全审核可在https://github.com/jaegertracing/security-audits中获得。有关Jaeger中可用安全机制的摘要,请参见问题#1718。

1.2.8、与Zipkin的向后兼容性

尽管我们建议使用OpenTracing API来对应用程序进行检测并绑定到Jaeger客户端库,以从其他地方无法获得的高级功能中受益,但是如果您的组织已经使用Zipkin库对检测进行了投资,则不必重写所有代码。Jaeger通过在HTTP上接受Zipkin格式(Thrift或JSON v1 / v2)的跨度来提供与Zipkin的向后兼容性。从Zipkin后端切换只是将流量从Zipkin库路由到Jaeger后端的问题。

1.3、jaeger架构:

(详见官网:)

2、下载安装编译jaeger

2.1、直接下载编译好的、适用于不同系统的jaeger

下载地址:https://www.jaegertracing.io/download/

下载对应平台的压缩包后,后解压、配置path路径即可。

2.2、本地编译

安装msys2环境或者cygwin环境

编译需要msys2环境或者cygwin环境。最好在虚拟机的纯linux环境中来执行编译。

安装yarn、dep、cross-env

npm install yarn -y

npm install dep -y

npm install cross-env -y

npm install --global cross-env

yarn global add cross-env

安装yarn:npm install -global yarn -y

安装nodejs

要求版本20以上,请从官网Index of /dist/v22.6.0/下载。

下载代码

下载指定branch或者tag的分支代码

git clone --recurse-submodules GitHub - jaegertracing/jaeger: CNCF Jaeger, a Distributed Tracing Platform

如果没能成功下载子项目 jaeger-ui,需要在 jaeger 项目的根目录下执行如下命令:

git clone --recurse-submodules https://github.com/jaegertracing/jaeger-ui  

    

项目编译

依赖工具安装

make  install-tools

可执行文件编译

make build-binaries-linux

jaeger-query 运行

jaeger_query  --query.port=${serverport}   --query.static-files=${jaeger-ui-filepath}   --query.base-path=/jaeger --es.server-urls=http://${ip}:${port} --es.username=${es_user} --es.password=${es_pwd}

query.port:服务监听端口

query.static-files: 静态文件的路径,一般为index.html 所在的文件夹

query.base-path:浏览器中URL的前缀,参数中的 /jaeger就是后面URL中的 /jaeger,http://127.0.0.1:32765/jaeger/search,--query.base-path=/xxx/jaeger 这样的话访问默认IP端口就会跳转到  http://127.0.0.1:32765/xxx/jaeger/search

3、测试用的All in One多功能一体的启动方式

多功能一体是一个为快速本地测试而设计的可执行文件。它包括Jaeger-UI、Jaeger收集器、Jaeger-query和Jaeger-agent,以及一个内存存储组件。

3.1、启动方式

(1)docker启动(仅能用于测试环境)

启动多功能一体的最简单方法是使用发布到DockerHub的预构建映像(单个命令行)。

docker run --rm --name jaeger \

  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \

  -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.59

(2)可执行文件启动(仅能用于测试环境)

jaeger-all-in-one --collector.zipkin.host-port=:9411

4、Kubernetes启动方式

Please see Kubernetes Operator: https://github.com/jaegertracing/jaeger-operator

5、生产环境启动方式

特别注意:all-in-one的方式将所有的数据存储在计算机内存中,给计算机内存带来巨大负担,同时,当all-in-one关闭后,所有的jaeger数据也会全部清空,因此,不建议在生产环境中使用all-in-one的方式;

5.1、组件说明

(1)jaeger-all-in-one(只能测试的时候使用!)

专为快速本地测试而设计。它通过内存存储组件启动Jaeger UI、collector收集器、query查询和agent代理。

(2)jaeger-agent代理(已弃用!)

从Jaeger客户端接收跨度并转发给收集器。设计为作为sidecar或host agent运行。jaeger代理已弃用,不再建议使用,请参阅https://github.com/jaegertracing/jaeger/issues/4739。

建议直接使用jaeger-collector收集器。

(3)jaeger-collector收集器

从代理或直接从客户端接收跨度,并将其保存在持久存储中。

这些代理可以是SpringBoot的项目。

(4)jaeger-ingester(针对kafka,这里不适用!)

收集器的替代品;从Kafka主题读取跨度并将其保存到存储中。

(5)jaeger-query查询

提供Jaeger UI和API,用于从存储中检索跟踪。

5.2、安装配置cassandra数据库(也可以选择配置es)

如何安装、配置cassandra数据,详见Cassandra安装部署相关文章。

在这里,Cassandra安装部署在hyper-v虚拟机中。

启动cassandra数据库的方式:cassandra -R

访问cassandra数据看得方式:cqlsh <IP> <端口>

5.3、在cassandra数据中建立对应的数据库和数据表

1、创建建表脚本create.sh

官方提供的create.sh内容地址:

jaeger/plugin/storage/cassandra/schema at main · jaegertracing/jaeger · GitHub

create.sh内容:

#!/usr/bin/env bash

function usage {

    >&2 echo "Error: $1"

    >&2 echo ""

    >&2 echo "Usage: MODE=(prod|test) [PARAM=value ...] $0 [template-file] | cqlsh"

    >&2 echo ""

    >&2 echo "The following parameters can be set via environment:"

    >&2 echo "  MODE               - prod or test. Test keyspace is usable on a single node cluster (no replication)"

    >&2 echo "  DATACENTER         - datacenter name for network topology used in prod (optional in MODE=test)"

    >&2 echo "  TRACE_TTL          - time to live for trace data, in seconds (default: 172800, 2 days)"

    >&2 echo "  DEPENDENCIES_TTL   - time to live for dependencies data, in seconds (default: 0, no TTL)"

    >&2 echo "  KEYSPACE           - keyspace (default: jaeger_v1_{datacenter})"

    >&2 echo "  REPLICATION_FACTOR - replication factor for prod (default: 2 for prod, 1 for test)"

    >&2 echo "  VERSION            - Cassandra backend version, 3 or 4 (default: 4). Ignored if template is provided."

    >&2 echo ""

    >&2 echo "The template-file argument must be fully qualified path to a v00#.cql.tmpl template file."

    >&2 echo "If omitted, the template file with the highest available version will be used."

    exit 1

}

trace_ttl=${TRACE_TTL:-172800}

dependencies_ttl=${DEPENDENCIES_TTL:-0}

cas_version=${VERSION:-4}

template=$1

if [[ "$template" == "" ]]; then

    case "$cas_version" in

        3)

            template=$(dirname $0)/v003.cql.tmpl

            ;;

        4)

            template=$(dirname $0)/v004.cql.tmpl

            ;;

        *)

            template=$(ls $(dirname $0)/*cql.tmpl | sort | tail -1)

            ;;

    esac

fi

if [[ "$MODE" == "" ]]; then

    usage "missing MODE parameter"

elif [[ "$MODE" == "prod" ]]; then

    if [[ "$DATACENTER" == "" ]]; then usage "missing DATACENTER parameter for prod mode"; fi

    datacenter=$DATACENTER

    replication_factor=${REPLICATION_FACTOR:-2}

    replication="{'class': 'NetworkTopologyStrategy', '$datacenter': '${replication_factor}' }"

elif [[ "$MODE" == "test" ]]; then

    datacenter=${DATACENTER:-'test'}

    replication_factor=${REPLICATION_FACTOR:-1}

    replication="{'class': 'SimpleStrategy', 'replication_factor': '${replication_factor}'}"

else

    usage "invalid MODE=$MODE, expecting 'prod' or 'test'"

fi

keyspace=${KEYSPACE:-"jaeger_v1_${datacenter}"}

if [[ $keyspace =~ [^a-zA-Z0-9_] ]]; then

    usage "invalid characters in KEYSPACE=$keyspace parameter, please use letters, digits or underscores"

fi

if [ ! -z "$COMPACTION_WINDOW" ]; then

    if echo "$COMPACTION_WINDOW" | grep -E -q '^[0-9]+[mhd]$'; then

        compaction_window_size="$(echo "$COMPACTION_WINDOW" | sed 's/[mhd]//')"

        compaction_window_unit="$(echo "$COMPACTION_WINDOW" | sed 's/[0-9]//g')"

    else

        usage "Invalid compaction window size format. Please use numeric value followed by 'm' for minutes, 'h' for hours, or 'd' for days."

    fi

else

    trace_ttl_minutes=$(( $trace_ttl / 60 ))

    # Taking the ceiling of the result

    compaction_window_size=$(( ($trace_ttl_minutes + 30 - 1) / 30 ))

    compaction_window_unit="m"

fi

case "$compaction_window_unit" in

    m) compaction_window_unit="MINUTES" ;;

    h) compaction_window_unit="HOURS" ;;

    d) compaction_window_unit="DAYS" ;;

esac

>&2 cat <<EOF

Using template file $template with parameters:

    mode = $MODE

    datacenter = $datacenter

    keyspace = $keyspace

    replication = ${replication}

    trace_ttl = ${trace_ttl}

    dependencies_ttl = ${dependencies_ttl}

    compaction_window_size = ${compaction_window_size}

    compaction_window_unit = ${compaction_window_unit}

EOF

# strip out comments, collapse multiple adjacent empty lines (cat -s), substitute variables

cat $template | sed \

    -e 's/--.*$//g'                                               \

    -e 's/^\s*$//g'                                               \

    -e "s/\${keyspace}/${keyspace}/g"                             \

    -e "s/\${replication}/${replication}/g"                       \

    -e "s/\${trace_ttl}/${trace_ttl}/g"                           \

    -e "s/\${dependencies_ttl}/${dependencies_ttl}/g"             \

    -e "s/\${compaction_window_size}/${compaction_window_size}/g" \

    -e "s/\${compaction_window_unit}/${compaction_window_unit}/g" | cat -s

将create.sh转成unix符号:dos2unix ./create.sh

2、获取对应的表结构

参考文章:https://www.jianshu.com/p/41d423ab8cce

表结构地址:jaeger/plugin/storage/cassandra/schema at main · jaegertracing/jaeger · GitHub

本地存储的表结构位置:D:\Program\jaeger\cassandra表结构

需要注意的是,不同版本的jaeger使用的表结构不同。

当前版本比较高,因此使用v004.cql.tmpl来建表。

3、进入cassandra数据库,并建立对应的数据库和数据表

在控制台输入命令:cqlsh 192.168.77.31 9042

然后进入到数据库中。

(1)建立数据库jaeger_v1_prod:

CREATE KEYSPACE jaeger_v1_prod WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };

(2)使用数据库jaeger_v1_prod:

use  jaeger_v1_prod

(3)建立数据表service_names、operation_names:

sudo MODE=prod DATACENTER=prod ./create.sh /mnt/share/v004.cql.tmpl  | cqlsh 192.168.77.31 9042

其中,create.sh文件是官方提供的sh导入建表的脚本。

5.4、启动方式

实际部署中,如果不使用kafka可以仅仅开启两个应用:jaeger-collector收集器、jaeger-query查询

1、配置PATH系统环境变量

首先,需要配置PATH系统环境变量:

SPAN_STORAGE_TYPE=cassandra

SAMPLING_STORAGE_TYPE=cassandra

2、启动jaeger-collector收集器

直接在控制台执行命令:

jaeger-collector.exe --cassandra.keyspace jaeger_v1_prod --cassandra.servers 192.168.77.31 --cassandra.port 9042

3、启动jaeger-query查询

直接在控制台执行命令:

jaeger-query.exe --cassandra.keyspace jaeger_v1_prod --cassandra.servers 192.168.77.31 --cassandra.port 9042

*4、docker启动方式参考(这里不适用!)

docker run -d --name=jaeger-collector -p 9411:9411 -p 14250:14250 -p 14268:14268 -p 14269:14269 -e SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://1.2.1.5:9200 -e ES_INDEX_PREFIX=test jaegertracing/jaeger-collector:1.38

docker run -d --name=jaeger-agent -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778/tcp -p 5775:5775/udp -e REPORTER_GRPC_HOST_PORT=1.2.1.5:14250 jaegertracing/jaeger-agent:1.38

docker run -d --name=jaeger-query -p 16686:16686 -p 16687:16687 -e SPAN_STORAGE_TYPE=elasticsearch -e ES_SERVER_URLS=http://1.2.1.5:9200 -e ES_INDEX_PREFIX=test jaegertracing/jaeger-query:1.38

Jaeger Spark依赖项 这是一个Spark作业,它从存储中收集跨度,分析服务之间的链接,并将其存储以供以后在UI中呈现

docker pull jaegertracing/spark-dependencies:latest

下面这个是执行一次的,会自动退出,每次更新需要执行一次

docker run -d --name=jaeger-spark -e STORAGE=elasticsearch -e ES_NODES=http://1.2.1.5:9200 -e ES_INDEX_PREFIX=test jaegertracing/spark-dependencies:latest

6、访问jaeger前端

直接访问:http://localhost:16686、http://localhost:16686/search,就可以打开jaeger页面。

7、jaeger相关端口说明

以下端口基本固定,不建议擅自改动。

Port

Protocol

Component

Function

6831

UDP

agent

accept jaeger.thrift over Thrift-compact protocol (used by most SDKs)

6832

UDP

agent

accept jaeger.thrift over Thrift-binary protocol (used by Node.js SDK)

5775

UDP

agent

(deprecated) accept zipkin.thrift over compact Thrift protocol (used by legacy clients only)

5778

HTTP

agent

serve configs (sampling, etc.)

16686

HTTP

query

serve frontend

4317

HTTP

collector

accept OpenTelemetry Protocol (OTLP) over gRPC

4318

HTTP

collector

accept OpenTelemetry Protocol (OTLP) over HTTP

14268

HTTP

collector

accept jaeger.thrift directly from clients

14250

HTTP

collector

accept model.proto

9411

HTTP

collector

Zipkin compatible endpoint (optional)

6、SpringBoot集成jaeger

创建项目,准备实施 Jaeger 跟踪

我们从https://start.spring.io创建一个只有一个“Spring Web”依赖项的应用程序。

引入jeager依赖

生成并下载代码后,我们会将以下 Jaeger 依赖项添加到 pom 文件中,这将有助于在服务之间生成和传播跟踪。

<dependency>

   <groupId>io.opentracing.contrib</groupId>

   <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>

   <version>3.3.1</version>

</dependency>

编写controller

有了这个,让我们添加一个带有一些路径的控制器。

@RestController

@RequestMapping("/service")

public class Controller {

    private static final Logger logger = LoggerFactory.getLogger(Controller.class);

    private RestTemplate restTemplate;

    @Value("${spring.application.name}")

    private String applicationName;

    public Controller(RestTemplate restTemplate) {

        this.restTemplate = restTemplate;

    }

    @GetMapping("/path1")

    public ResponseEntity path1() {

        logger.info("Incoming request at {} for request /path1 ", applicationName);

        String response = restTemplate.getForObject("http://localhost:8090/service/path2", String.class);

        return ResponseEntity.ok("response from /path1 + " + response);

    }

    @GetMapping("/path2")

    public ResponseEntity path2() {

        logger.info("Incoming request at {} at /path2", applicationName);

        return ResponseEntity.ok("response from /path2 ");

    }

}

在这里,我们有两个端点:/path1和/path2。这里的想法是使用同一应用程序的两个实例,以便在固定端口 8090/path1调用另一个服务。/path2

*创建一个RestTemplate bean(不是必须的)

为了使跨度连接到相同的跟踪 ID,我们需要创建一个 RestTemplate bean 以允许 Jaeger 包含一个拦截器。然后,这有助于向传出请求添加跟踪,这将有助于跟踪整个请求。

@Bean

public RestTemplate restTemplate(RestTemplateBuilder builder) {

return builder.build();

}

配置yml

现在,让我们添加一些属性以允许应用程序将跟踪发送到 Jaeger 服务器。我们将通过 TCP 进行通信,因此请确保我们将跟踪发送到另一个 TCP 端口,即 14268

opentracing:

  jaeger:

    http-sender:

      url: http://localhost:14268/api/traces

启动SpringBoot测试服务

让我们使用以下命令启动“服务器 1”。

java -jar

target/Distributed-Service-0.0.1-SNAPSHOT.jar

--spring.application.name=Service-1

--server.port=8080

然后在不同的终端上,运行与“服务 2”相同的应用程序的新实例,如下所示

java -jar

target/Distributed-Service-0.0.1-SNAPSHOT.jar

--spring.application.name=Service-2

--server.port=8090

测试微服务之间的服务调用

应用程序启动后,调用“Service 1”,/path1如下所示

curl -i http://localhost:8080/service/path1

让我们看一下“服务1”的日志。

INFO 69938 --- [nio-8080-exec-1] i.j.internal.reporters.LoggingReporter   : Span reported: ed70bbaa2bd5b42f:c7c94163fc95fc1e:ed70bbaa2bd5b42f:1 - GET

跟踪的格式为 [Root Span ID, Current Span ID, Parent Span ID]。在这种情况下,由于“服务 1”是发起服务,因此父跨度 IDed70bbaa2bd5b42f也是根跨度 ID。

现在,让我们看一下“服务 2”的​日志。

INFO 69885 --- [nio-8090-exec-1] i.j.internal.reporters.LoggingReporter   : Span reported: ed70bbaa2bd5b42f:e9060cb1d5336c55:c7c94163fc95fc1e:1 - path2

从这里我们看到中间值是当前 span ID,父 span ID(即第三个值c7c94163fc95fc1e)是“Service 1”的 span ID。

查看jaeger前端展示的跟踪信息

直接访问:http://localhost:16686,就可以打开jaeger页面。

如果您打开 UI,您将看到以下内容:

当我们深入挖掘时,我们会看到每个跨度的更多细节。

在这里,根跨度 IDed70bbaa2bd5b42f跨越整个请求。其他两个跨度 ID 指的是单个服务。

7、分布式链路追踪的基本概念

分布式链路追踪是一种监控和分析分布式系统中请求流动的方法。它能够记录和分析一个请求在系统中经历的每一步操作,帮助开发者和运维人员了解系统的性能和行为。在微服务架构中,一个请求可能会跨越多个服务节点,而每个服务节点又可能依赖其他多个服务。分布式链路追踪通过生成一个唯一的跟踪ID(Trace ID),并在每个服务节点生成一个跨度(Span),记录每个操作的详细信息,从而形成完整的请求链路。

Span 和 Trace

Trace:表示一个完整的请求链路,从请求发起到请求完成,包含了所有相关的 Spans。

Span:表示 Trace 中的一个单独的操作单元,包含操作的开始时间、结束时间、操作名称、相关的元数据(如标签、日志)等信息。一个 Trace 由多个 Spans 组成,形成一个有向无环图(DAG)。

上下文传播

在分布式系统中,请求在不同服务节点之间传递时,需要传递跟踪信息以保持 Trace 的连续性。上下文传播是指将 Trace ID 和 Span ID 等信息通过 HTTP 头、消息队列等方式在服务之间传递,使得每个服务都能够关联到同一个 Trace。

采样策略

由于分布式系统中的请求量通常非常大,记录每一个请求的详细信息会带来巨大的存储和性能开销。采样策略通过对请求进行采样,只记录部分请求的跟踪信息,从而减少开销。常见的采样策略包括随机采样、基于请求类型的采样、基于错误率的采样等。

8、分布式链路追踪的工作原理

分布式链路追踪的核心工作原理包括以下几个步骤:

请求拦截:在请求进入系统时,生成一个唯一的 Trace ID,并为每个操作生成 Span ID。将这些跟踪信息注入到请求的上下文中。

上下文传播:在请求在服务之间传递时,将跟踪信息通过 HTTP 头、消息队列等方式传递,确保每个服务节点都能获取到跟踪信息。

数据收集:每个服务节点在处理请求时,记录当前 Span 的详细信息,包括开始时间、结束时间、操作名称、元数据等。

数据传输:将收集到的跟踪数据通过日志、消息队列等方式传输到集中式的跟踪存储系统中。

数据存储:将跟踪数据存储在分布式存储系统中,以便后续查询和分析。

数据展示:通过可视化工具展示跟踪数据,帮助用户分析和诊断系统行为。

9、常见的分布式链路追踪系统

Zipkin

Zipkin 是 Twitter 开源的一个分布式链路追踪系统,能够帮助用户收集和分析系统中的跟踪数据。Zipkin 的核心组件包括:

Zipkin Collector:负责收集跟踪数据并存储到后端存储系统中。

Zipkin Query:提供查询接口,允许用户通过 API 或 Web 界面查询跟踪数据。

Zipkin Web UI:提供可视化界面,帮助用户分析和展示跟踪数据。

Jaeger

Jaeger 是 Uber 开源的分布式链路追踪系统,设计初衷是解决微服务架构中的监控和故障排除问题。Jaeger 提供了与 Zipkin 类似的功能,并在可扩展性和性能上进行了优化。Jaeger 的核心组件包括:

Jaeger Agent:运行在主机上,负责收集应用程序发送的跟踪数据并转发给 Jaeger Collector。

Jaeger Collector:接收 Jaeger Agent 发送的跟踪数据并存储到后端存储系统中。

Jaeger Query:提供查询接口,允许用户通过 API 或 Web 界面查询跟踪数据。

Jaeger UI:提供可视化界面,帮助用户分析和展示跟踪数据。

OpenTelemetry

OpenTelemetry 是一个联合的开源项目,由 OpenTracing 和 OpenCensus 项目合并而来,旨在为分布式系统提供统一的监控、跟踪和日志收集工具。OpenTelemetry 提供了 SDK 和 API,支持多种编程语言,并与多种后端系统兼容。OpenTelemetry 的核心组件包括:

OpenTelemetry SDK:提供多种编程语言的 SDK,帮助开发者在应用程序中集成跟踪功能。

OpenTelemetry Collector:一个独立的服务,负责收集、处理和导出跟踪数据。

OpenTelemetry Protocol:统一的协议,支持多种后端系统,如 Jaeger、Zipkin、Prometheus 等。

10、分布式链路追踪的技术实现

数据收集

数据收集是分布式链路追踪的第一步,需要在每个服务节点中集成跟踪 SDK,以拦截和记录请求的详细信息。常见的集成方式包括:

拦截器:在 HTTP 请求的入口和出口处添加拦截器,生成和记录 Span 信息。

中间件:在应用程序中使用中间件,自动处理跟踪信息的生成和传播。

手动注入:在代码中手动添加跟踪信息的生成和记录逻辑。

数据传输

数据传输负责将收集到的跟踪数据发送到集中式的存储系统中。常见的传输方式包括:

日志文件:将跟踪数据写入日志文件,通过日志收集系统(如 ELK Stack)集中处理和存储。

消息队列:通过消息队列(如 Kafka、RabbitMQ)传输跟踪数据,确保数据的可靠传输和处理。

HTTP 请求:直接通过 HTTP 请求将跟踪数据发送到后端存储系统。

数据存储

数据存储负责将传输到的跟踪数据持久化,支持高效的查询和分析。常见的存储系统包括:

关系型数据库:如 MySQL、PostgreSQL,适用于小规模的跟踪数据存储。

分布式数据库:如 Cassandra、Elasticsearch,适用于大规模的跟踪数据存储,支持高并发和快速查询。

对象存储:如 Amazon S3、Google Cloud Storage,适用于冷数据存储,成本较低。

数据展示

数据展示通过可视化工具将跟踪数据展示给用户,帮助用户分析

和诊断系统行为。常见的可视化工具包括:

Zipkin Web UI:提供基本的跟踪数据查询和展示功能,支持时序图、依赖关系图等。

Jaeger UI:提供丰富的跟踪数据查询和展示功能,支持高级查询、时序图、依赖关系图等。

Grafana:通过插件支持展示跟踪数据,能够与其他监控数据(如指标、日志)集成,提供统一的监控视图。

11、分布式链路追踪的应用场景

性能优化

通过分布式链路追踪,开发者能够清晰地看到请求在系统中的每一步操作及其耗时,从而识别性能瓶颈。例如,某个服务响应时间过长,或某个数据库查询耗时过多,开发者可以据此进行优化,提升系统整体性能。

故障排除

在分布式系统中,定位故障原因往往非常困难。分布式链路追踪通过记录详细的请求流动信息,帮助运维人员快速定位故障点。例如,某个请求在某个服务节点出现错误,或某个服务依赖的外部接口不可用,运维人员可以通过跟踪数据迅速找到问题所在,进行修复。

依赖分析

分布式链路追踪能够展示系统中各个服务之间的依赖关系,帮助开发者和运维人员更好地理解系统架构。例如,通过依赖关系图可以看到某个服务依赖了哪些其他服务,这些服务又依赖了哪些外部系统,从而更好地进行系统设计和优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值