Administrator
发布于 2026-04-03 / 8 阅读
0
0

分布式链路追踪

前言

微服务拆分后,服务调用链路复杂,出现问题很难定位,但分布式链路追踪能把一次请求流经的所有服务、耗时、报错都串起来,可视化展示调用流程。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 version

b.结果图:

显示版本及为成功


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)
EOF

b.结果图

  • 服务A

  • 服务B

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

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



评论