如何在Kubernetes上使用Jaeger实现分布式跟踪
作者选择了 COVID-19 Relief Fund 作为 Write for DOnations 计划的一部分来接受捐赠。
介绍
Kubernetes 及其支持的微服务架构可以创建非常高效和可扩展的系统。 但是,当这些微服务之一出现性能问题时,就会出现问题。 通常,我们首先注意到我们面向客户的服务的响应时间越来越长。 问题可能出在后端服务之一,或者可能是超出其最佳容量的数据库。 为了发现我们问题的根源,我们需要实现分布式跟踪。
Jaeger 是一个分布式追踪解决方案,毕业于云原生计算基金会孵化项目。 它具有用于可视化跟踪的令人愉快的 UI、用于收集跟踪的 Jaeger sidecars 以及其他几个组件。 像 Jaeger 这样的分布式跟踪系统让我们可以跟踪每个客户生成的事件的生命周期,并查看每个服务如何处理该事件。
在本教程中,我们将在 Kubernetes 集群中部署一个非常小的分布式应用程序,并在我们的代码中使用 sleep 函数来模拟性能滞后。 为了找到此问题的根本原因并跟踪每个事件,我们将使用 Jaeger。 启用跟踪后,我们将看到它在观察服务行为和查明问题方面的有效性。
先决条件
在开始之前,您将需要以下工具和帐户:
- 一个 Kubernetes 1.15+ 集群,您的连接配置设置为
kubectl
默认值。 要在 DigitalOcean 上创建 Kubernetes 集群,请阅读我们的 Kubernetes 快速入门 。 要连接到集群,请阅读 如何连接到 DigitalOcean Kubernetes 集群。 - 安装了 Docker。 请按照我们关于 如何安装和使用 Docker 的教程获取说明。 Docker 的网站 提供了 macOS 和 Windows 等其他操作系统的安装说明。
- Docker Hub 上的一个帐户,用于存储您的 Docker 映像。
kubectl
命令行工具安装在您的本地机器上并配置为连接到您的集群。 您可以在官方文档中阅读更多关于安装kubectl
的信息,或者按照本教程开始使用Kubernetes:A kubectl Cheat Sheet。- 安装在本地机器上的 curl 命令行实用程序 。 您可以使用操作系统内置的包管理器安装
curl
。
第 1 步 - 构建示例应用程序
为了测试 Jaeger 的跟踪能力,我们将构建和部署一个示例应用程序 sammy-jaeger
,它使用两个服务:一个用于前端,一个用于后端。 我们将使用 Python 和 Flask 微框架 进行构建。
我们的应用程序将是一个计数器,每次调用前端时它的值都会增加。 为了模拟性能问题,我们将编写一个随机休眠函数,只要前端向后端发送 GET
请求,该函数就会执行。 在这一步中,我们将构建和部署该应用程序。 在接下来的步骤中,我们会将应用程序部署到 Kubernetes,安装 Jaeger,然后使用它来跟踪我们的服务问题。
首先,让我们创建一个项目目录结构并在里面导航:
mkdir -p ./sammy-jaeger/frontend ./sammy-jaeger/backend && cd ./sammy-jaeger
我们现在有一个根目录 sammy-jaeger
和两个子目录:
output. ├── backend └── frontend
我们也进入了根目录,/sammy-jaeger
。 我们将从这里运行所有剩余的命令。
让我们开始构建前端应用程序。
构建前端应用程序
使用您喜欢的文本编辑器,在 ./frontend
中创建并打开一个名为 frontend.py
的新文件:
nano ./frontend/frontend.py
添加以下代码。 这将导入 Flask,构建我们的计数器函数,并为 HTTP 请求定义一个路由:
./前端/前端.py
import os import requests from flask import Flask app = Flask(__name__) def get_counter(counter_endpoint): counter_response = requests.get(counter_endpoint) return counter_response.text def increase_counter(counter_endpoint): counter_response = requests.post(counter_endpoint) return counter_response.text @app.route('/') def hello_world(): counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000") counter_endpoint = f'{counter_service}/api/counter' counter = get_counter(counter_endpoint) increase_counter(counter_endpoint) return f"""Hello, World! You're visitor number {counter} in here!\n\n"""
我们正在导入三个模块。 os 模块将与我们的操作系统进行通信。 requests 模块是一个用于发送 HTTP 请求的库。 Flask 是一个微框架,将托管我们的应用程序。
然后我们定义我们的 get_counter()
和 increase_counter()
函数,它们都接受参数 counter_endpoint
。 get_counter()
将使用 GET
方法调用后端以查找当前计数器状态。 increase_counter()
将使用 POST
方法调用后端来增加计数器。
然后我们定义我们的路由 /
,它将调用另一个名为 hello_world()
的函数。 此函数将为我们的后端 pod 检索 URL 和端口,将其分配给一个变量,然后将该变量传递给我们的前两个函数 get_counter()
和 increase_counter()
,这将发送 [ X192X] 和 POST
向后端请求。 然后后端将暂停一段随机时间(我们模拟的延迟),然后增加当前计数器编号,然后返回该编号。 最后,hello_world()
将获取该值并打印“Hello World!” 字符串到我们的控制台,其中包括我们的新访客人数。
您可能已经注意到我们没有创建 Python 环境,也没有在本地机器上安装 pip
。 当我们使用 Docker 容器化我们的应用程序时,我们将完成这些步骤。
保存并关闭 frontend.py
。
现在我们将为前端应用程序构建一个 Dockerfile。 该 Dockerfile 将包含构建容器化环境所需的所有命令。
在./frontend
中新建并打开一个新的Dockerfile
:
nano ./frontend/Dockerfile
添加以下内容:
./frontend/Dockerfile
FROM alpine:3.8 RUN apk add --no-cache py3-pip python3 && \ pip3 install flask requests COPY . /usr/src/frontend ENV FLASK_APP frontend.py WORKDIR /usr/src/frontend CMD flask run --host=0.0.0.0 --port=8000
在这个 Dockerfile
中,我们指示我们的镜像从基础 Alpine Linux 镜像构建。 然后我们安装 Python3、pip
和几个额外的依赖项。 接下来,我们复制应用程序源代码,设置一个指向主应用程序代码的环境变量,设置工作目录,并在我们从镜像创建容器时编写运行 Flask 的命令。
保存并关闭文件。
现在让我们为我们的前端应用程序构建 Docker 映像并将其推送到 Docker Hub 中的存储库。
首先,检查您是否已登录 Docker Hub:
docker login --username=your_username --password=your_password
构建镜像:
docker build -t your_username/do-visit-counter-frontend:v1 ./frontend
现在将图像推送到 Docker Hub:
docker push your_username/do-visit-counter-frontend:v1
我们的前端应用程序现已在 Docker Hub 中构建并可用。 然而,在我们将其部署到 Kubernetes 之前,让我们编写代码并构建我们的后端应用程序。
构建后端应用程序
后端应用程序需要与前端相同的步骤。
首先,在 ./backend
中创建并打开一个名为 backend.py
的文件:
nano ./backend/backend.py
添加以下内容,这将定义两个函数和另一个路由:
./后端/后端.py
from random import randint from time import sleep from flask import request from flask import Flask app = Flask(__name__) counter_value = 1 def get_counter(): return str(counter_value) def increase_counter(): global counter_value int(counter_value) sleep(randint(1,10)) counter_value += 1 return str(counter_value) @app.route('/api/counter', methods=['GET', 'POST']) def counter(): if request.method == 'GET': return get_counter() elif request.method == 'POST': return increase_counter()
我们正在导入几个模块,包括 random
和 sleep
。 然后我们将计数器值设置为 1
并定义两个函数。 第一个,get_counter
,返回当前计数器值,存储为 counter_value
。 第二个函数 increase_counter
执行两个动作。 它将计数器值增加 1
并使用 sleep
模块将函数的完成延迟随机时间。
后端还有一个路由 (/api/counter
),它接受两种方法:POST
和 GET
。 当我们使用 GET
方法调用此路由时,它会调用 get_counter()
并返回我们的计数器值。 当我们使用 POST
方法调用此路由时,它会调用 increase_counter()
并在等待随机时间的同时增加计数器的值。
保存并关闭文件。
我们的后端应用程序还需要自己的 Dockerfile
,这与前端的版本几乎相同。
在 ./backend
中创建并打开第二个 Dockerfile
:
nano ./backend/Dockerfile
添加以下内容。 除了文件路径之外,这里的一个主要区别是端口:
./backend/Dockerfile
FROM alpine:3.8 RUN apk add --no-cache py3-pip python3 && \ pip3 install flask COPY . /usr/src/backend ENV FLASK_APP backend.py WORKDIR /usr/src/backend CMD flask run --host=0.0.0.0 --port=5000
保存并关闭文件。
现在构建图像:
docker build -t your_username/do-visit-counter-backend:v1 ./backend
将其推送到 Docker Hub:
docker push your_username/do-visit-counter-backend:v1
我们的应用程序在 Docker Hub 上可用,我们现在准备将其部署到我们的集群并在下一步中对其进行测试。
第 2 步 — 部署和测试应用程序
编写代码和发布容器是我们的第一个重要步骤。 现在我们需要部署到 Kubernetes 并测试基本应用程序。 之后,我们可以添加 Jaeger 并探索分布式跟踪的潜力。
让我们开始部署和测试。
此时,我们的目录树如下所示:
. ├── backend │ ├── Dockerfile │ └── backend.py └── frontend ├── Dockerfile └── frontend.py
要将这个应用程序部署到我们的集群,我们还需要两个 Kubernetes manifests; 每半份申请一份。
在 ./frontend
中创建并打开一个新的清单文件:
nano ./frontend/deploy_frontend.yaml
添加以下内容。 此清单将指定 Kubernetes 如何构建我们的 Deployment(请记住将突出显示的部分替换为您的 Docker Hub 用户名):
./frontend/deploy_frontend.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: do-visit-counter-frontend labels: name: do-visit-counter-frontend spec: replicas: 1 selector: matchLabels: app: do-visit-counter-frontend template: metadata: labels: app: do-visit-counter-frontend spec: containers: - name: do-visit-counter-frontend image: your_dockerhub_username/do-visit-counter-frontend:v1 imagePullPolicy: Always env: - name: COUNTER_ENDPOINT value: "http://do-visit-counter-backend.default.svc.cluster.local:5000" ports: - name: frontend-port containerPort: 8000 protocol: TCP
我们已经指定 Kubernetes 来构建一个 Deployment,将其命名为 do-visit-counter-frontend
,并使用我们在 Docker Hub 上的前端映像部署一个副本。 我们还配置了一个名为 COUNTER_ENDPOINT
的环境变量来链接我们应用程序的两个部分。
保存并关闭文件。
现在在 ./backend
中为我们的后端应用程序创建清单:
nano ./backend/deploy_backend.yaml
添加以下内容,再次将突出显示的部分替换为您的 Docker Hub 用户名:
./backend/deploy_backend.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: do-visit-counter-backend labels: name: do-visit-counter-backend spec: replicas: 1 selector: matchLabels: app: do-visit-counter-backend template: metadata: labels: app: do-visit-counter-backend spec: containers: - name: do-visit-counter-backend image: your_dockerhub_username/do-visit-counter-backend:v1 imagePullPolicy: Always ports: - name: backend-port containerPort: 5000 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: do-visit-counter-backend spec: selector: app: do-visit-counter-backend ports: - protocol: TCP port: 5000 targetPort: 5000
在这个清单中,您正在为我们的后端定义一个部署和一个 Service。 部署描述了容器将如何运行以及运行什么。 请注意,我们的端口已从前端的 8000
更改为后端的 5000
。 该服务允许从前端到后端的集群间连接。
保存并关闭文件。
现在让我们使用 kubectl
将计数器部署到集群。 从前端开始:
kubectl apply -f ./frontend/deploy_frontend.yaml
然后部署后端:
kubectl apply -f ./backend/deploy_backend.yaml
要验证一切正常,请调用 kubectl get pods
:
kubectl get pods
你会看到这样的输出:
OutputNAME READY STATUS RESTARTS AGE do-visit-counter-backend-79f6964-prqpb 1/1 Running 0 3m do-visit-counter-frontend-6985bdc8fd-92clz 1/1 Running 0 3m
我们希望所有 pod 都处于 READY
状态。 如果它们尚未准备好,请等待几分钟并重新运行上一个命令。
最后,我们要使用我们的应用程序。 为此,我们将转发来自集群的端口,然后使用 curl
命令与前端通信。 确保打开第二个终端窗口,因为转发端口会阻塞一个窗口。
使用 kubectl
转发端口:
kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000
现在,在第二个终端窗口中,向您的前端应用程序发送三个请求:
for i in 1 2 3; do curl localhost:8000; done
每个 curl
调用都会增加访问次数。 你会看到这样的输出:
OutputHello, World! You're visitor number 1 in here! Hello, World! You're visitor number 2 in here! Hello, World! You're visitor number 3 in here!
我们的访客柜台工作正常,但您可能注意到每次响应之间存在延迟。 这是我们的 sleep 函数的结果,它模拟了性能滞后。
准备好我们的分布式应用程序后,就可以安装 Jaeger 并跟踪这些事件了。
第 3 步 — 部署 Jaeger
收集痕迹并将其可视化是 Jaeger 的专长。 在这一步中,我们会将 Jaeger 部署到我们的集群中,以便它可以发现我们的性能滞后。
Jaeger 官方文档中包含安装 Jaeger Operator 的命令。 它还包括四个额外的清单,您必须部署这些清单才能使该工具正常工作。 现在让我们这样做:
首先,创建 Jaeger Operator 所需的 Custom Resource Definition。 我们将使用 Jaeger 官方文档 中提供的推荐模板:
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml
接下来,为 Role-Based Access Control 创建一个 Service Account、一个 Role 和 Role Binding:
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml
最后,部署 Jaeger Operator:
kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml
Operator 本身并不意味着我们让 Jaeger 工作。 这就是自定义资源定义发挥作用的地方。 我们需要创建一个资源来描述我们希望 Operator 管理的 Jaeger 实例。 再次,我们将按照 Jaeger 官方文档中列出的步骤进行操作:
使用 heredoc 从命令行创建此资源:
kubectl apply -f - <<EOF apiVersion: jaegertracing.io/v1 kind: Jaeger metadata: name: simplest EOF
按 ENTER
创建资源。
现在再次检查您的部署:
kubectl get pods
您将看到 Jaeger 操作员和 simplest
部署的输出:
OutputNAME READY STATUS RESTARTS AGE do-visit-counter-backend-79f6964-prqpb 1/1 Running 0 3m do-visit-counter-frontend-6985bdc8fd-92clz 1/1 Running 0 3m jaeger-operator-547567dddb-rxsd2 1/1 Running 0 73s simplest-759cb7d586-q6x28 1/1 Running 0 42s
为了验证 Jaeger 是否正常工作,让我们转发它的端口,看看我们是否可以访问 UI:
kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686
打开浏览器并导航到 http://localhost:16686
。 Jaeger UI 将加载。
我们的应用程序和 Jaeger 都在工作。 在下一步中,我们将添加检测以让 Jaeger 收集数据并找出我们的性能滞后。
第 4 步 — 添加仪器
尽管 Jaeger 在与 Kubernetes 一起使用时会自动执行许多任务,但我们仍然需要手动将检测添加到我们的应用程序中。 幸运的是,我们有 Flask-OpenTracing 模块 来处理该任务。
OpenTracing是分布式追踪的标准之一。 它由 Jaeger 的作者提出,旨在支持其他跟踪工具。 它与供应商无关,支持许多不同的编程语言和流行的框架。
与所有 OpenTracing 实现的情况一样,我们需要通过添加 Jaeger 配置并将跟踪装饰器附加到我们想要跟踪的端点来修改我们的原始应用程序。
让我们将 Flask-OpenTracing 添加到我们的前端代码中。
重新打开 .frontend.py
:
nano ./frontend/frontend.py
现在添加以下突出显示的代码,它将嵌入 OpenTracing:
./前端/前端.py
import os import requests from flask import Flask from jaeger_client import Config from flask_opentracing import FlaskTracing app = Flask(__name__) config = Config( config={ 'sampler': {'type': 'const', 'param': 1}, 'logging': True, 'reporter_batch_size': 1,}, service_name="service") jaeger_tracer = config.initialize_tracer() tracing = FlaskTracing(jaeger_tracer, True, app) def get_counter(counter_endpoint): counter_response = requests.get(counter_endpoint) return counter_response.text def increase_counter(counter_endpoint): counter_response = requests.post(counter_endpoint) return counter_response.text @app.route('/') def hello_world(): counter_service = os.environ.get('COUNTER_ENDPOINT', default="https://localhost:5000") counter_endpoint = f'{counter_service}/api/counter' counter = get_counter(counter_endpoint) increase_counter(counter_endpoint) return f"""Hello, World! You're visitor number {counter} in here!\n\n"""
保存并关闭文件。 您可以在他们的 GitHub 页面 上了解有关 Flask OpenTracing 配置的更多信息。
现在打开您的后端应用程序代码:
nano ./backend/backend.py
添加突出显示的代码。 这与我们在 frontend.py
中放置的代码相同:
./后端/后端.py
from random import randint from time import sleep from flask import Flask from flask import request from jaeger_client import Config from flask_opentracing import FlaskTracing app = Flask(__name__) config = Config( config={ 'sampler': {'type': 'const', 'param': 1}, 'logging': True, 'reporter_batch_size': 1,}, service_name="service") jaeger_tracer = config.initialize_tracer() tracing = FlaskTracing(jaeger_tracer, True, app) counter_value = 1 def get_counter(): return str(counter_value) def increase_counter(): global counter_value int(counter_value) sleep(randint(1,10)) counter_value += 1 return str(counter_value) @app.route('/api/counter', methods=['GET', 'POST']) def counter(): if request.method == 'GET': return get_counter() elif request.method == 'POST': return increase_counter()
保存并关闭文件。
由于我们要添加额外的库,我们还必须为这两个服务修改我们的 Dockerfiles
。
打开前端的Dockerfile
:
nano ./frontend/Dockerfile
添加突出显示的代码:
./frontend/Dockerfile
FROM alpine:3.8 RUN apk add --no-cache py3-pip python3 && \ pip3 install flask requests Flask-Opentracing jaeger-client COPY . /usr/src/frontend ENV FLASK_APP frontend.py WORKDIR /usr/src/frontend CMD flask run --host=0.0.0.0 --port=8000
保存并关闭文件。
现在打开后端的Dockerfile
:
nano ./backend/Dockerfile
添加突出显示的代码:
./backend/Dockerfile
FROM alpine:3.8 RUN apk add --no-cache py3-pip python3 && \ pip3 install flask Flask-Opentracing jaeger-client COPY . /usr/src/backend ENV FLASK_APP backend.py WORKDIR /usr/src/backend CMD flask run --host=0.0.0.0 --port=5000
通过这些更改,我们希望重建和推送容器的新版本。
构建并推送前端应用程序。 注意末尾的 v2
标签:
docker build -t your_username/do-visit-counter-frontend:v2 ./frontend docker push your_username/do-visit-counter-frontend:v2
现在构建并推送后端应用程序:
docker build -t your_username/do-visit-counter-backend:v2 ./backend docker push your_username/do-visit-counter-backend:v2
我们的分布式跟踪系统需要最后一个部分:我们希望将 Jaeger sidecars 注入到我们的应用程序 pod 中,以监听来自 pod 的跟踪并将它们转发到 Jaeger 服务器。 为此,我们需要在清单中添加一个 注释。
打开前端的清单:
nano ./frontend/deploy_frontend.yaml
添加突出显示的代码。 请注意,我们还将我们的图像替换为 v2
版本。 确保修改该行并添加您的 Docker Hub 用户名:
./frontend/deploy_frontend.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: do-visit-counter-frontend labels: name: do-visit-counter-frontend annotations: "sidecar.jaegertracing.io/inject": "true" spec: replicas: 1 selector: matchLabels: app: do-visit-counter-frontend template: metadata: labels: app: do-visit-counter-frontend spec: containers: - name: do-visit-counter-frontend image: your_dockerhub_username/do-visit-counter-frontend:v2 imagePullPolicy: Always env: - name: COUNTER_ENDPOINT value: "http://do-visit-counter-backend.default.svc.cluster.local:5000" ports: - name: frontend-port containerPort: 8000 protocol: TCP
这个注解会将一个 Jaeger sidecar 注入到我们的 pod 中。
保存并关闭文件。
现在打开后端的清单:
nano ./backend/deploy_backend.yaml
重复该过程,添加突出显示的行以注入 Jaeger sidecar 并更新您的图像标签:
./backend/deploy_backend.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: do-visit-counter-backend labels: name: do-visit-counter-backend annotations: "sidecar.jaegertracing.io/inject": "true" spec: replicas: 1 selector: matchLabels: app: do-visit-counter-backend template: metadata: labels: app: do-visit-counter-backend spec: containers: - name: do-visit-counter-backend image: your_dockerhub_username/do-visit-counter-backend:v2 imagePullPolicy: Always ports: - name: backend-port containerPort: 5000 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: do-visit-counter-backend spec: selector: app: do-visit-counter-backend ports: - protocol: TCP port: 5000 targetPort: 5000
有了新的清单,我们需要将它们应用到集群并等待 pod 创建。
让我们删除我们的旧资源:
kubectl delete -f ./frontend/deploy_frontend.yaml kubectl delete -f ./backend/deploy_backend.yaml
然后替换它们:
kubectl apply -f ./frontend/deploy_frontend.yaml kubectl apply -f ./backend/deploy_backend.yaml
这一次,我们应用程序的 pod 将包含两个容器:一个用于应用程序,另一个用于 Jaeger sidecar。
使用 kubectl
来检查:
kubectl get pods
我们的应用程序 pod 现在在 READY
列中显示为 2/2
:
OutputNAME READY STATUS RESTARTS AGE jaeger-operator-547567dddb-rxsd2 1/1 Running 0 23m simplest-759cb7d586-q6x28 1/1 Running 0 22m do-visit-counter-backend-694c7db576-jcsmv 2/2 Running 0 73s do-visit-counter-frontend-6d7d47f955-lwdnf 2/2 Running 0 42s
有了我们的边车和仪器,现在我们可以重新运行我们的程序并调查 Jaeger UI 中的跟踪。
第 5 步 — 在 Jaeger 中调查踪迹
现在我们可以从追踪中获益。 这里的目标是通过查看 Jaeger UI 来了解哪些调用可能是性能问题。 当然,如果我们想在 UI 中看到一些痕迹,我们首先必须使用我们的应用程序生成一些数据。
让我们通过打开第二个和第三个终端窗口来设置它。 我们将使用两个窗口来端口转发 Jaeger 和我们的应用程序,第三个窗口通过 curl
从我们的机器向前端发送 HTTP 请求。
在第一个窗口中,转发前端服务的端口:
kubectl port-forward $(kubectl get pods -l=app="do-visit-counter-frontend" -o name) 8000:8000
在第二个窗口中,转发 Jaeger 的端口:
kubectl port-forward $(kubectl get pods -l=app="jaeger" -o name) 16686:16686
在第三个窗口中,循环使用 curl
生成 10 个 HTTP 请求:
for i in 0 1 2 3 4 5 6 7 8 9; do curl localhost:8000; done
您将收到像以前一样的输出:
OutputHello, World! You're visitor number 1 in here! Hello, World! You're visitor number 2 in here! . . . Hello, World! You're visitor number 10 in here!
这将为我们提供足够的不同数据点来在可视化中比较它们。
打开浏览器并导航到 http://localhost:16686
。 将 Service 下拉菜单设置为 service 并将 limit results 更改为 30
。 按查找轨迹。
我们应用程序的跟踪将出现在图表中:
在这里,我们看到对服务的不同调用具有不同的执行时间。 Jaeger 跟踪了我们的应用程序处理信息所需的时间以及哪些功能贡献的时间最多。 请注意,由于我们的 sleep 函数,我们的 hello_world()
函数完成所需的时间是高度可变的。 这是非常可疑的,它为我们提供了一个集中调查的地方。 Jaeger 有效地可视化了我们分布式应用程序内部的性能泄漏。
通过实施跟踪和使用 Jaeger UI,我们能够找到导致响应时间不规律的原因。
结论
在本文中,我们使用 Jaeger 建立了一个分布式跟踪系统,并将检测添加到一个小型应用程序中。 现在我们可以将其他工作负载部署到集群中,注入 Jaeger Sidecar,并查看我们的各种服务如何交互以及哪些操作花费的时间最多。
使用分布式跟踪可以更快地发现使用多个服务的应用程序中的性能瓶颈。 然而,这个例子只展示了 Jaeger 潜力的一小部分。 在更复杂的生产环境中,您可以使用 Jaeger 比较不同的跟踪,并真正深入挖掘性能漏洞。 Jaeger 可以生成的复杂可视化效果非常令人印象深刻且非常有用。 要了解有关 Jaeger 如何帮助您监控和解决集群中的性能问题的更多信息,请访问他们的官方文档。