Zipkin 工具手册
Zipkin 的价值在兼容边界
Zipkin 的 v2 数据模型、HTTP API 和 B3 传播格式仍承载许多历史接入。它的服务端由 Collector、Storage、Query API 和 Web UI 组成:Reporter 异步发送完成的 Span,Collector 校验并持久化,Query 读取存储,UI 消费 Query API。官方 Zipkin architecture 也明确提醒 UI 没有内置认证。
新项目不必因此继续绑定 Zipkin Reporter。更稳妥的入口是 OpenTelemetry SDK 把 OTLP 发给 Collector,再由 zipkin exporter 转成 Zipkin v2。OTLP 和 Zipkin JSON 是不同协议;端口开放不代表负载可以互换。
用 v2 API 建立最小证据
准备一个只含合成属性的 Span 数组:
TRACE_LAB_DIR=$(mktemp -d)
TRACE_ID=463ac35c9f6413ad48485a3953bb6124
SPAN_ID=a2fb4a1d1a96d312
NOW_US=$(($(date +%s) * 1000000))
cat > "$TRACE_LAB_DIR/span.json" <<JSON
[{
"traceId": "$TRACE_ID",
"id": "$SPAN_ID",
"kind": "SERVER",
"name": "POST /checkout",
"timestamp": $NOW_US,
"duration": 820000,
"localEndpoint": {"serviceName": "checkout-api"},
"tags": {"http.method":"POST","http.status_code":"504","deployment.environment":"trace-lab"}
}]
JSONZipkin v2 要求最外层是数组,trace ID 为 16 或 32 位十六进制,span ID 为 16 位,timestamp 使用微秒,duration 为正数。启动固定的实验镜像并写入:
docker run -d --name zipkin-lab \
-p 127.0.0.1:29411:9411 \
openzipkin/zipkin:3.6.1
curl -fsS http://localhost:29411/health
curl -fsS -X POST http://localhost:29411/api/v2/spans \
-H 'Content-Type: application/json' --data-binary @"$TRACE_LAB_DIR/span.json"
curl -fsS "http://localhost:29411/api/v2/trace/$TRACE_ID"查询结果应是包含固定 trace ID 的 Span 数组。InvalidApiVersion、JSON 解析错误或 415 分别指向 API 路径、负载形状、Content-Type 或协议。把 OTLP protobuf 直接 POST 到 /api/v2/spans 不会自动转换。
docker rm -f zipkin-lab
docker run -d --name zipkin-lab -p 127.0.0.1:29411:9411 openzipkin/zipkin:3.6.1
curl -i "http://localhost:29411/api/v2/trace/$TRACE_ID"重建后丢失证明默认内存存储只适合实验。健康端点、写入响应、按 ID 查询和重启后查询应分别记录,不能用一张 UI 截图替代。
Storage 决定真实容量
Zipkin 原生支持 Cassandra、Elasticsearch 和 MySQL 等可插拔后端。Cassandra 适合高写入和按主键访问,但修复、压实与磁盘治理成本高;Elasticsearch 提供更强搜索,代价是索引、heap、分片与版本兼容;MySQL 便于已有数据库团队接管,规模上升后索引写放大和查询竞争会更早暴露。
“支持某后端”不等于默认配置适合生产。必须用真实采样率、每 Trace Span 数、属性大小、保留期和查询条件压测。精确 trace ID 读取与按 service、annotation 和时间范围搜索属于不同负载,后端索引和 TTL 也要分别验证。
Collector 的数据库运行账号只获得所需 schema 权限,初始化或迁移账号应独立。凭证放入 Secret,不写进 Compose。存储备份还要做恢复演练;内存模式重启丢失不能通过“多跑几个 Zipkin 副本”解决。
Query 与写入必须分权
Zipkin 的 9411 端口同时可能暴露写入和查询,UI 没有内置认证。生产入口至少在代理层按路径、HTTP 方法和身份分权:应用只能写 Span,值班和受控自动化才能查询,管理与存储初始化属于另一身份。
内网不是认证机制。Trace 常包含 URL、异常栈、消息 key、数据库操作和用户关联字段,查询历史数据的权限应可审计。Authorization、Cookie、连接串、完整请求体与 SQL 参数应在 SDK 或 Collector 删除,而不是等 UI 前面加了登录再处理。
B3 与 W3C Trace Context 不能靠“双开”解决
旧 Zipkin 链路常使用 B3 单头或多头,新 OpenTelemetry 链路通常使用 W3C Trace Context 的 traceparent 与 tracestate。后端能接收 Zipkin Span,不代表服务间传播已经统一。
迁移期间如果入口同时提取两种格式,必须规定冲突优先级;如果同时注入两套头,要验证下游不会各自创建新根 Span。正确证据是同一业务请求从入口到数据库保持一个 trace ID,父子关系、采样标志和错误状态一致,而不是两个页面都出现相似调用。
异步线程、消息队列和代理是最容易断传播的边界。出现零散根 Span 时先对照请求头、消息属性和 SDK propagator,不要调数据库 TTL 或扩大搜索窗口。
让 OpenTelemetry Collector 隔离后端
应用只向 OTLP Collector 导出,Collector 再转换为 Zipkin v2:
exporters:
zipkin/legacy:
endpoint: http://zipkin:9411/api/v2/spans
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [zipkin/legacy]这样应用仓库只维护 service.name、环境、版本和 OTLP endpoint。后端迁移可以在平台仓库短期双写,不需要修改所有应用。双写会增加出口带宽和队列压力,因此必须有固定样本、接收数量、完整 Trace 比例和明确停止条件。
Service 列表为空时,先查 SDK 采样、Collector accepted/refused 和 exporter send_failed,再看 Zipkin Collector。按 ID 能查而条件搜索为空时,检查 Span 是否真的携带该 tag、存储实现的搜索能力、时间范围和索引状态。近期可查而历史丢失,检查持久化后端、TTL 与数据库健康。
错误响应要回到协议层
POST /api/v2/spans 返回 202 只说明 Collector 接受了当前批次。400 通常属于 JSON 形状、ID、时间戳或字段类型,404 常见于路径写错,415 指向 Content-Type 或负载协议;连接成功却使用 OTLP body 仍然是协议错误。发送器应区分不可重试的格式错误和可恢复的后端故障,永久错误不能在本地队列中无限循环。
查询 API 返回空数组时,先用精确 trace ID 排除时间筛选,再核对 Collector 和 Query 是否连接同一 Storage。服务列表来自存储中的聚合信息,短暂延迟与完全没有 Span 是两种状态。数据库拒绝、TTL 提前过期、索引未刷新和查询权限错误都应在代理、Zipkin 日志或存储指标中留下可关联证据。
容量不能只记录每天 Trace 数。还要测每 Trace Span 数、单 Span 属性字节、写入批次、数据库索引放大、查询并发和最宽时间窗。采样降低写入量,却不能修复动态 service name、完整 URL 或用户 ID 带来的搜索基数。运行基线应把 Collector 拒绝、数据库写延迟、查询尾延迟和存储增长放在同一看板上。
把兼容入口设计成可退役
Zipkin 退役不应先修改所有应用 endpoint。先让 Collector 将一小部分确定样本双写到新后端,比较 Span 数、父子关系、搜索延迟、历史窗口和权限;新后端通过故障演练后,停止 Zipkin 新写入但保留旧查询。
B3 提取可以保留一个有限兼容窗口,但应用导出应尽快统一到 OTLP。旧 Reporter、专用消息 transport 和 B3-only SDK 都要有 owner 与退出顺序。否则 Zipkin 服务端即使空了,最后一个历史依赖仍会阻止关停。
docker rm -f zipkin-lab
if [ -n "${TRACE_LAB_DIR:-}" ] && [ -d "$TRACE_LAB_DIR" ]; then
rm -rf -- "$TRACE_LAB_DIR"
fi这段清理只适用于唯一命名的本机实验。生产退出先停止写入、保留只读窗口、完成合规归档,再撤销查询入口、数据库账号和存储;drop schema 与对象删除是独立审批动作。Zipkin 的长期价值是清晰、稳定的兼容边界,而不是让兼容协议永久成为新系统默认。
