zipkin
Zipkin 是一个开源分布式追踪系统。zipkin 插件对网关请求进行插桩,并通过 Zipkin v2 HTTP API 将采样后的 Span 发送到 Collector。
该插 件也适用于公开兼容 Zipkin v2 端点的 Collector,例如 Jaeger 和 Apache SkyWalking。
追踪会为每个采样请求增加额外开销。请使用 sample_ratio 在追踪覆盖率与开销之间取得平衡;如果高吞吐路由不需要全量采样,请使用较低的采样率。未被采样的请求不会构建 Span 标签。请结合实际流量和 Collector 配置测量影响,而不要假定固定的性能提升。
示例
以下示例使用 Zipkin 和 Jaeger Collector 配置 zipkin 插件,比较其两种 Span 层级,并将 Trace ID 公开给访问日志。
以下 Collector 部署使用临时内存存储,且未启用身份认证或 TLS。生产环境中,请配置持久化存储并保护 Collector 端点,然后相应更新插件端点。
发送追踪到 Zipkin
插件始终向配置的端点发送 Zipkin v2 JSON。span_version 设置控制网关如何将请求处理划分为 Span,但不会改变 Zipkin 传输格式。此示例将追踪发送到 Zipkin,并比较两种受支持的 Span 层级。
在 Docker 中启动一个 Zipkin 实例:
- Docker
- Kubernetes
将 GATEWAY_CONTAINER 设置为正在运行的 APISIX 或 API7 网关容器名称。创建专用网络并将网关连接到该网络:
export GATEWAY_CONTAINER=replace-with-gateway-container-name
docker network create gateway-zipkin-net
docker network connect gateway-zipkin-net "$GATEWAY_CONTAINER"
在同一网络中启动 Zipkin,并仅在环回接口上发布其 HTTP 服务:
docker run -d --name zipkin \
--network gateway-zipkin-net \
-p 127.0.0.1:9411:9411 \
openzipkin/zipkin:3.6.1
等待 Zipkin 就绪:
until curl -fsS "http://127.0.0.1:9411/health" > /dev/null; do
sleep 1
done
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: zipkin
spec:
replicas: 1
selector:
matchLabels:
app: zipkin
template:
metadata:
labels:
app: zipkin
spec:
containers:
- name: zipkin
image: openzipkin/zipkin:3.6.1
ports:
- containerPort: 9411
readinessProbe:
httpGet:
path: /health
port: 9411
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: zipkin
spec:
selector:
app: zipkin
ports:
- name: http
port: 9411
targetPort: 9411
应用清单:
kubectl apply -f zipkin-server.yaml
等待 Zipkin 可用:
kubectl rollout status -n aic deployment/zipkin
以下配置标签页将 Admin API 和 ADC 与 Docker Collector 配合使用,将 Ingress Controller 与 Kubernetes Collector 配合使用。如果使用其他部署组合,请将端点替换为网关可访问的 Collector Zipkin v2 端点。
创建一个启用了 zipkin 的路由,并使用默认的跨度版本 2:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes/zipkin-tracing-route" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/anything",
"plugins": {
"zipkin": {
"endpoint": "http://zipkin:9411/api/v2/spans",
"sample_ratio": 1,
"span_version": 2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /anything
name: zipkin-tracing-route
plugins:
zipkin:
endpoint: "http://zipkin:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
ADC 会将服务作为期望状态进行协调。标签选择器将此示例限制在其自身带标签 的资源内。请先预览限定范围的变更,并确认其中没有意外更新或删除:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
同步已审查的服务配置:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-route
spec:
ingressClassName: apisix
http:
- name: zipkin-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
将配置应用到集群:
kubectl apply -f zipkin-ic.yaml
❶ 将 Span 发送到 Collector 的 Zipkin v2 HTTP 端点。Docker 和 Kubernetes 示例使用网关可访问的地址。
❷ 在此示例中追踪每个请求。不需要全量采样的环境应使用较低的采样率。
❸ 使用默认 Span 层级。
发送请求到该路由:
curl "http://127.0.0.1:9080/anything"
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-6aa8b24c-29cf898f18bbdf415ccd7b42",
"X-B3-Parentspanid": "e1a7df5f617b3a04",
"X-B3-Sampled": "1",
"X-B3-Spanid": "c3a11943cd04ec70",
"X-B3-Traceid": "b06793db23230f51187a9638e08fb772",
"X-Forwarded-Host": "127.0.0.1:9080"
},
"json": null,
"method": "GET",
"url": "http://127.0.0.1:9080/anything"
}
对于 Kubernetes,请在单独的终端会话中将 Zipkin UI 暴露到本地:
kubectl port-forward -n aic service/zipkin 9411:9411
等待异步导出的追踪可用:
until curl -fsS \
"http://127.0.0.1:9411/api/v2/traces?serviceName=APISIX&limit=10" | \
grep -q '"traceId"'; do
sleep 1
done
打开 http://127.0.0.1:9411/zipkin 的 Zipkin Web UI,选择 Run Query。你应该会看到与该请求对应的追踪:

选择 Show 查看 Span 详情:

对于此示例中成功代理的请求,span_version: 2 会生成以下 Span:
apisix.request
├── apisix.proxy
└── apisix.response_span
apisix.proxy Span 覆盖从请求开始到 NGINX header_filter 阶段开始的时间。apisix.response_span Span 覆盖从 header_filter 开始到 log 阶段开始的时间。
请求 Span 包含 apisix.response_source 标签,用于将响应来源分类为 apisix(由网关生成,例如插件拒绝)、nginx(NGINX 代理错误)或 upstream(上游服务的真实响应)。此功能自 API7 企业版 3.9.10 和 APISIX 3.17.0 起引入。
现在,更新路由上的插件以使用跨度版本 1:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes/zipkin-tracing-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"zipkin": {
"span_version": 1
}
}
}'
更新 adc.yaml,将 span_version 设置为 1:
services:
- name: httpbin
routes:
- uris:
- /anything
name: zipkin-tracing-route
plugins:
zipkin:
endpoint: "http://zipkin:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
ADC 会将服务作为期望状态进行协调。标签选择器将此示例限制在其自身带标签的资源内。请先预览限定范围的变更,并确认其中没有意外更新或删除:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
同步已审查的服务配置:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
- Gateway API
- APISIX CRD
更新 zipkin-ic.yaml,将 span_version 设置为 1:
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
更新 zipkin-ic.yaml,将 span_version 设置为 1:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-route
spec:
ingressClassName: apisix
http:
- name: zipkin-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
重新应用配置:
kubectl apply -f zipkin-ic.yaml
发送另一个请求到该路由:
curl "http://127.0.0.1:9080/anything"
等待新追踪可用,然后在 Zipkin UI 中打开。其 Span 层级应与以下截图类似:

对于此示例中成功代理的请求,span_version: 1 会生成以下 Span。由于该设置只改变网关 Span 层级,端点仍为 /api/v2/spans:
apisix.request
├── apisix.rewrite
├── apisix.access
└── apisix.proxy
└── apisix.body_filter
发送追踪到 Jaeger
Jaeger v2 的 All-in-One 配置包含 Zipkin Receiver。以下示例通过其 Zipkin v2 Receiver 将 Span 发送到 Jaeger,以便存储和可视化。
在 Docker 中启动一个 Jaeger 实例:
- Docker
- Kubernetes
将 GATEWAY_CONTAINER 设置为正在运行的 APISIX 或 API7 网关容器名称。创建专用网络并将网关连接到该网络:
export GATEWAY_CONTAINER=replace-with-gateway-container-name
docker network create gateway-jaeger-net
docker network connect gateway-jaeger-net "$GATEWAY_CONTAINER"
在同一网络中启动 Jaeger,并仅在环回接口上发布其 UI:
docker run -d --name jaeger \
--network gateway-jaeger-net \
-p 127.0.0.1:16686:16686 \
cr.jaegertracing.io/jaegertracing/jaeger:2.20.0
等待 Jaeger 就绪:
until curl -fsS "http://127.0.0.1:16686/" > /dev/null; do
sleep 1
done
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: cr.jaegertracing.io/jaegertracing/jaeger:2.20.0
ports:
- containerPort: 16686
- containerPort: 9411
readinessProbe:
httpGet:
path: /
port: 16686
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: jaeger
spec:
selector:
app: jaeger
ports:
- name: ui
port: 16686
targetPort: 16686
- name: zipkin
port: 9411
targetPort: 9411
应用清单:
kubectl apply -f jaeger-server.yaml
等待 Jaeger 可用:
kubectl rollout status -n aic deployment/jaeger
以下配置标签页将 Admin API 和 ADC 与 Docker Collector 配合使用,将 Ingress Controller 与 Kubernetes Collector 配合使用。如果使用其他部署组合,请将端点替换为网关可访问的 Jaeger Zipkin v2 Receiver 地址。
创建一个带有 zipkin 插件的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes/zipkin-jaeger-route" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/anything/jaeger",
"plugins": {
"zipkin": {
"endpoint": "http://jaeger:9411/api/v2/spans",
"sample_ratio": 1
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /anything/jaeger
name: zipkin-jaeger-route
plugins:
zipkin:
endpoint: "http://jaeger:9411/api/v2/spans"
sample_ratio: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
ADC 会将服务作为期望状态进行协调。标签选择器将此示例限制在其自身带标签的资源内。请先预览限定范围的变更,并确认其中没有意外更新或删除:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
同步已审查的服务配置:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=zipkin-tracing
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-jaeger-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://jaeger.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-jaeger-route
spec:
parentRefs:
- name: apisix
hostnames:
- "jaeger.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-jaeger-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-jaeger-route
spec:
ingressClassName: apisix
http:
- name: zipkin-jaeger-route
match:
hosts:
- "jaeger.example.com"
paths:
- /*
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://jaeger.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
将配置应用到集群:
kubectl apply -f zipkin-jaeger-ic.yaml
❶ 将 Span 发送到 Jaeger 内置的 Zipkin v2 Receiver。Docker 和 Kubernetes 示例使用网关可访问的地址。
❷ 在此示例中追踪每个请求。
发送请求到该路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9080/anything/jaeger"
curl "http://127.0.0.1:9080/anything/jaeger"
curl "http://127.0.0.1:9080/anything" -H "Host: jaeger.example.com"
你应该收到 HTTP/1.1 200 OK 响应。
对于 Kubernetes,请在单独的终端会话中将 Jaeger UI 暴露到本地:
kubectl port-forward -n aic service/jaeger 16686:16686
等待异步导出的追踪可用:
until curl -fsS \
"http://127.0.0.1:16686/api/traces?service=APISIX&limit=10&lookback=1h" | \
grep -q '"traceID"'; do
sleep 1
done
打开 http://127.0.0.1:16686 的 Jaeger Web UI,选择 APISIX 服务,再选择 Find Traces。你应该会看到与该请求对应的追踪:

打开追踪以检查其 Span 层级和耗时:

在日志中使用追踪变量
此示例沿用将追踪发送到 Zipkin 中配置的 Zipkin Collector 和 /anything 路由。
插件可以填充以下内置变量,供日志插件和访问日志使用:
zipkin_context_traceparent:根据请求 Span 上下文生成的 W3Ctraceparent值zipkin_trace_id:请求 Span 的 Trace IDzipkin_span_id:请求 Span 的 Span ID
启用这些变量的访问日志输出,并允许插件设置 NGINX 变量:
- Host or Docker
- Kubernetes (Helm)
在网关配置文件中新增或更新以下配置:
nginx_config:
http:
enable_access_log: true
access_log_format: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
access_log_format_escape: json
plugin_attr:
zipkin:
set_ngx_var: true
❶ access_log_format:在访问日志中包含 zipkin 插件变量。
❷ set_ngx_var:填充 zipkin NGINX 变量。
重新加载网关以使配置更改生效。
对于 Helm 部署,请更新用于渲染访问日志格式和 plugin_attr.zipkin 的 values,并保留 values 文件中的其他配置。
对于 APISIX Helm Chart, 设置以下 values:
apisix:
nginx:
logs:
enableAccessLog: true
accessLogFormat: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
accessLogFormatEscape: json
pluginAttrs:
zipkin:
set_ngx_var: true
对于 API7 网关 Helm Chart,设置以下 values:
logs:
enableAccessLog: true
accessLogFormat: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
accessLogFormatEscape: json
pluginAttrs:
zipkin:
set_ngx_var: true
然后使用当前网 关 release 对应的 Chart 应用 values 文件。请将 <chart-version> 替换为已安装发布版本所使用的版本:
helm upgrade <release-name> <chart-name> \
--version <chart-version> \
-n <namespace> \
-f values.yaml
通过已启用追踪的路由发送请求:
curl "http://127.0.0.1:9080/anything"
你应该会看到与以下内容类似的访问日志条目:
{"time": "2026-09-15T16:25:58+00:00","zipkin_context_traceparent": "00-7931097725ec577a17fe02a5c067a440-66ae231b61fef3ef-01","zipkin_trace_id": "7931097725ec577a17fe02a5c067a440","zipkin_span_id": "66ae231b61fef3ef","remote_addr": "192.168.158.1"}