跳到主要内容
版本:3.10.x

配置分布式追踪

分布式追踪可以端到端展示请求经过 API7 网关和后端服务的路径。API7 网关使用 opentelemetry 插件生成跨度,并通过 OTLP/HTTP 将其发送到 Jaeger、Tempo、OpenTelemetry Collector、Honeycomb、Datadog、New Relic、AWS X-Ray 等兼容 Collector。

工作原理

opentelemetry 插件有两层配置:

  • 插件元数据:由网关组中的所有路由共享,控制 Collector 端点、请求超时、自定义标头、批量跨度处理器和 Trace ID 来源。每个网关组通过 /apisix/admin/plugin_metadata/opentelemetry 设置一次。
  • 路由插件配置:设置在路由、Service 或全局规则上,控制采样策略和匹配流量的额外跨度属性。

在任何路由产生有用跨度之前,必须至少为网关组配置一次插件元数据。

前置条件

  • 运行中的 API7 网关部署,且至少有一个在线数据面;
  • 数据面可以访问 OTLP/HTTP Collector(以下示例使用 Jaeger 的 4318 端口);
  • 令牌管理

步骤一:配置 Collector 端点

在插件元数据中设置 Collector 地址。生产环境应根据流量调整批量跨度处理器和请求超时;默认的 127.0.0.1:4318 和 3 秒超时通常不适用。

curl -k "https://localhost:7443/apisix/admin/plugin_metadata/opentelemetry?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"trace_id_source": "x-request-id",
"resource": {
"service.name": "api7-gateway",
"deployment.environment": "production"
},
"collector": {
"address": "jaeger:4318",
"request_timeout": 3
},
"set_ngx_var": true
}'

set_ngx_var: true 会将 Trace ID 和 Span ID 暴露为 $opentelemetry_trace_id$opentelemetry_span_id NGINX 变量,用于关联追踪和访问日志。如果 Collector 需要认证,请在 collector.request_headers 下添加标头。

步骤二:在路由上启用追踪

启用插件并选择采样策略。默认采样器为 always_off,必须显式设置采样器才能开始捕获链路。以下示例先创建 Service 和路由,再通过全局规则覆盖网关组中的所有路由:

# 创建带上游的 Service
curl -k "https://localhost:7443/apisix/admin/services/tracing-demo?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "tracing-demo",
"upstream": {
"type": "roundrobin",
"nodes": [
{ "host": "httpbin.org", "port": 80, "weight": 1 }
]
}
}'

# 创建路由
curl -k "https://localhost:7443/apisix/admin/routes/tracing-demo?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "tracing-demo",
"service_id": "tracing-demo",
"paths": ["/anything"]
}'

# 通过全局规则为所有请求启用追踪
curl -k "https://localhost:7443/apisix/admin/global_rules/opentelemetry?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"plugins": {
"opentelemetry": {
"sampler": {
"name": "trace_id_ratio",
"options": { "fraction": 1.0 }
},
"additional_attributes": ["consumer_name", "request_uri"]
}
}
}'

additional_attributes 中的值使用 APISIX 变量名,例如 consumer_namerequest_uriroute_name。插件还会自动附加 http.routehttp.status_codeapisix.route_name 等 OpenTelemetry 语义属性。

选择采样策略

策略使用场景
always_on开发、预发布或低流量路由,需要追踪每个请求。
trace_id_ratio生产环境。选择如 0.01(1%)的比例,以限制 Collector 负载和存储成本。
parent_base上游服务或 Service Mesh 已经决定采样时,网关遵循其决定。
always_off默认策略。保留插件但暂时停止生成跨度。

生产环境常用 parent_base 配合低比例 trace_id_ratio 根采样器:

{
"sampler": {
"name": "parent_base",
"options": {
"root": {
"name": "trace_id_ratio",
"options": { "fraction": 0.01 }
}
}
}
}

步骤三:验证

通过网关发送请求:

curl -i "http://127.0.0.1:9080/anything"

打开 Collector 的 UI(Jaeger 使用 http://127.0.0.1:16686),搜索服务 api7-gateway。你应看到以请求方法和路径命名的跨度,例如 GET /anything,以及 http.status_codeapisix.route_name=tracing-demorequest_uri 等属性。

关联追踪和访问日志

当插件元数据中设置了 set_ngx_var: true 时,可将 Trace ID 和 Span ID 加入访问日志格式:

conf/config.yaml
nginx_config:
http:
access_log_format: '{"time": "$time_iso8601","trace_id": "$opentelemetry_trace_id","span_id": "$opentelemetry_span_id","remote_addr": "$remote_addr","status": "$status"}'
access_log_format_escape: json

同样的变量也可在 http-loggerkafka-logger 插件的 log_format 字段中使用。

后续步骤