作者选择了COVID-19 救济基金来接受捐赠,作为Write for DOnations计划的一部分。
介绍
Kubernetes及其支持的微服务架构可以创建非常高效且可扩展的系统。但是当这些微服务之一出现性能问题时就会出现问题。通常,我们首先注意到面向客户的服务的响应时间越来越长。问题可能出在其中一项后端服务上,也可能出在超出其最佳容量的数据库。为了发现问题的根源,我们需要实现分布式跟踪。
Jaeger 是分布式跟踪解决方案,毕业于云原生计算基金会孵化项目。它具有用于可视化跟踪的令人愉悦的 UI、用于收集跟踪的Jaeger sidecar以及其他几个组件。像 Jaeger 这样的分布式跟踪系统让我们可以跟踪每个客户生成事件的生命周期,并查看每个服务如何处理该事件。
在本教程中,我们将一个非常小的分布式应用程序部署到 Kubernetes 集群,并在我们的代码中使用睡眠函数模拟性能滞后。为了找到这个问题的根本原因并跟踪每个事件,我们将使用Jaeger。启用跟踪后,我们将看到它在观察服务行为和查明问题方面的有效性。
先决条件
在开始之前,您将需要以下工具和帐户:
- Kubernetes 1.15+ 集群,将您的连接配置设置为
kubectl
默认值。要在 DigitalOcean 上创建 Kubernetes 集群,请阅读我们的Kubernetes 快速入门。要连接到集群,请阅读如何连接到 DigitalOcean Kubernetes 集群。 - 安装了 Docker。按照我们关于如何安装和使用 Docker 的教程获取说明。Docker 的网站提供了其他操作系统(如 macOS 和 Windows)的安装说明。
- Docker Hub 上用于存储 Docker 映像的帐户。
kubectl
安装在本地机器上并配置为连接到集群的命令行工具。您可以kubectl
在官方文档中阅读有关安装的更多信息,或者按照本教程开始使用 Kubernetes:备忘kubectl
单。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.py
中./frontend
:
nano ./frontend/frontend.py
添加以下代码。这将导入 Flask,构建我们的计数器函数,并为 HTTP 请求定义一个路由:
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()
and increase_counter()
,它将向后端发送GET
和POST
请求。然后后端将在增加当前计数器编号并返回该编号之前随机暂停一段时间(我们的模拟滞后)。最后,hello_world()
将获取此值并打印“Hello World!” 字符串到我们的控制台,包括我们的新访问者计数。
您可能已经注意到,我们没有创建 Python 环境,也没有pip
在本地机器上安装。当我们使用 Docker 容器化我们的应用程序时,我们将完成这些步骤。
保存并关闭frontend.py
。
现在我们将为前端应用程序构建一个Dockerfile。此 Dockerfile 将包含构建我们的容器化环境所需的所有命令。
在 中创建并打开一个新Dockerfile
的./frontend
:
- nano ./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.py
在./backend
:
- nano ./backend/backend.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
,它几乎与前端的版本相同。
创建并打开第二个Dockerfile
在./backend
:
- nano ./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 清单;应用程序的每一半一个。
在以下位置创建并打开一个新的清单文件./frontend
:
- nano ./frontend/deploy_frontend.yaml
添加以下内容。此清单将指定 Kubernetes 如何构建我们的部署(请记住将突出显示的部分替换为您的 Docker Hub 用户名):
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 来构建部署,为其命名do-visit-counter-frontend
,并使用我们在 Docker Hub 上的前端映像部署一个副本。我们还配置了一个名为的环境变量COUNTER_ENDPOINT
来链接我们应用程序的两部分。
保存并关闭文件。
现在为我们的后端应用程序创建清单./backend
:
- nano ./backend/deploy_backend.yaml
添加以下内容,再次用您的 Docker Hub 用户名替换突出显示的部分:
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
在此清单中,您正在为我们的后端定义部署和服务。部署描述了容器将如何运行以及运行什么。请注意,我们的端口已从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
我们想要READY
状态中的所有 pod 。如果它们尚未准备好,请等待几分钟并重新运行上一个命令。
最后,我们要使用我们的应用程序。为此,我们将从集群转发端口,然后使用该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 所需的自定义资源定义。我们将使用Jaeger 官方文档中提供的推荐模板:
- kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml
- 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:
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
:
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
添加突出显示的代码:
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
添加突出显示的代码:
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 用户名:
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 并更新您的图像标签:
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 现在出现2/2
在READY
列中:
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
.
在第一个窗口中,转发前端服务的端口:
- 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
。将服务下拉菜单设置为服务并将限制结果更改为30
。按查找跟踪。
来自我们应用程序的跟踪将显示在图表中:
Here, we see that different calls to the service have different execution times. Jaeger has traced how long our applications take to process information and which functions contribute the most time. Notice how, as a result of our sleep function, the time it takes for our hello_world()
function to complete is highly variable. This is very suspicious, and it gives us a place to focus our investigation. Jaeger has effectively visualized the performance leak inside our distributed application.
By implementing tracing and using the Jaeger UI, we were able to find the cause of our irregular response time.
Conclusion
In this article, we set up a distributed tracing system using Jaeger and added instrumentation to a small application. Now we can deploy other workloads to the cluster, inject Jaeger sidecars, and see how our various services interact and what operations are taking the most time.
使用分布式跟踪可以更快地找到使用多个服务的应用程序中的性能瓶颈。然而,这个例子只展示了 Jaeger 潜力的一小部分。在更复杂的生产环境中,您可以使用 Jaeger 来比较不同的跟踪并真正深入研究性能泄漏。Jaeger 可以生成的复杂可视化效果令人印象深刻且非常有用。要详细了解 Jaeger 如何帮助您监控和解决集群中的性能问题,请访问他们的官方文档。