前言
微服务拆分后,服务调用链路复杂,出现问题很难定位,但分布式链路追踪能把一次请求流经的所有服务、耗时、报错都串起来,可视化展示调用流程。234
分布式链路追踪是用来干嘛的
我们可以吧微服务想象成:一个快递从发货 -> 中转 -> 派送的过程
服务 A = 发货点
服务 B = 中转仓
用户请求 = 一个快递
以前的问题:快递慢了、丢了、卡了,我们根本不知道卡在哪一步
现在我们使用的分布式链追踪,而这个部署包含使用Jaeger和OpenTelemetry
首先,我们可以把Jaeger想象成一个快递监控中心,它的作用就是一个查看物流路线图。
其次,我们再把OpenTelemetry想象成一个快递站点的扫码记录仪,它的作用就是每到一个站点,自动扫码上报
最后,我们发一个快递,也就是使用一个新终端,进行服务调试,看到Jaeger画出调用链,也就是看到一个完整路线
实验步骤
1.安装docker和docker compose
我们先安装docker容器,去部署Jaeger,这是为了避免环境依赖问题,我们也可以使用清华源,这是为了快速下载,也可以根据自身需求去官方下载或者本地下载。
a.操作命令
# 1. 更新软件源
sudo apt update
# 2. 安装依赖
sudo apt install -y ca-certificates curl gnupg lsb-release
# 3. 添加Docker GPG密钥
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 4. 添加清华源Docker仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 5. 手动添加缺失的公钥
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 7EA0A9C3F273FCD8
# 6. 安装Docker
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
# 7. 安装Docker Compose
sudo apt install -y docker-compose-plugin
# 8. 启动Docker服务
sudo systemctl start docker
# 9. 设置开机自启(避免重启后失效)
sudo systemctl enable docker
# 10. 验证服务状态(看到active (running)即成功)
sudo systemctl status docker
# 11. 验证安装
docker --version
docker compose versionb.结果图:
显示版本及为成功

2. 部署 Jaeger 追踪系统
这一步是为了Jaeger 负责收集链路数据、存储、展示可视化界面,是链路追踪的核心服务
a.操作命令
# 1. 创建部署文件夹:方便管理
mkdir yxwa-jaeger && cd yxwa-jaeger
# 2. 创建 docker-compose.yml,并写入配置
cat > docker-compose.yml << 'EOF'
services:
jaeger:
image: jaegertracing/all-in-one:1.58
container_name: yxwa-jaeger
environment:
- COLLECTOR_ZIPKIN_HOST_PORT=:9411
ports:
- "16686:16686"
- "4317:4317"
- "4318:4318"
- "6831:6831/udp"
- "9411:9411"
restart: always
EOF
# 4. 启动 Jaeger
sudo docker compose up -d
# 5. 访问浏览器进行验证
浏览器访问:http://服务器ip:16686,打开 Jaeger 界面b.结果图

3.编写 OpenTelemetry 微服务
我们需要用 OpenTelemetry 标准采集微服务的调用链路,发送给 Jaeger
我们这样做是为了,模拟微服务调用(服务 A 调用服务 B),用于测试链路追踪,以下内容我们使用python脚本进行
a.操作命令
安装依赖
# 1. 建服务文件夹 (以下操作都在这个文件夹下执行)
mkdir demo-service && cd demo-service
# 方式一,在虚拟环境里搭建(温和、安全,多项目使用)
# 2. 创建虚拟环境依赖包
sudo apt install python3-pip python3-venv python3-full -y
# 3. 创建虚拟环境
python3 -m venv venv
# 4. 安装依赖
pip install flask opentelemetry-sdk opentelemetry-exporter-otlp-proto-http requests
# 5. 激活虚拟环境(终端出现 (venv) 前缀即成功)
source venv/bin/activate
# 7. 启动服务B(脚本在下面)
python3 serviceB.py
# 8. 新终端(同样先激活虚拟环境 source venv/bin/activate)启动服务A
python3 serviceA.py
# 如果不行就使用以下依赖,再启动服务A/B
# . 激活venv 以后在虚拟环境里 安装所有依赖
pip install \
opentelemetry-distro \
opentelemetry-instrumentation-flask \
opentelemetry-instrumentation-requests \
opentelemetry-exporter-otlp-proto-http \
-i https://pypi.tuna.tsinghua.edu.cn/simple
# 执行自动 instrumentation 安装(补全所有依赖)
opentelemetry-bootstrap -a install
# 退出venv环境
deactivate服务A得python脚本
cat > ~/yxwa-jaeger/demo-service/serviceA.py << 'EOF'
from flask import Flask
import requests
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
# 配置追踪(服务名:yxwa-serviceA)
resource = Resource(attributes={"service.name": "yxwa-serviceA"})
trace.set_tracer_provider(TracerProvider(resource=resource))
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://172.16.11.234:4318/v1/traces"))
)
tracer = trace.get_tracer(__name__)
app = Flask(__name__)
# 接口:调用服务B
@app.route('/')
def index():
with tracer.start_as_current_span("serviceA-request"):
# 调用服务B
response = requests.get("http://127.0.0.1:5001/")
return f"服务A调用服务B:{response.text}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)
EOF服务B的python脚本
cat > ~/yxwa-jaeger/demo-service/serviceB.py << 'EOF'
from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
# 配置追踪(服务名:yxwa-serviceB)
resource = Resource(attributes={"service.name": "yxwa-serviceB"})
trace.set_tracer_provider(TracerProvider(resource=resource))
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(OTLPSpanExporter(endpoint="http://172.16.11.234:4318/v1/traces"))
)
tracer = trace.get_tracer(__name__)
app = Flask(__name__)
@app.route('/')
def index():
with tracer.start_as_current_span("serviceB-request"):
return "我是服务B"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001, debug=False)
EOFb.结果图
服务A

服务B

使用 curl http://172.16.11.234:5000/测试

使用 Jaeger 图形界面查看,service选择服务A/B
