将请求链路导出到 ClickHouse
AISIX 网关通过 OTLP/HTTP 导出请求链路(Trace)。可以将链路直接发送到 ClickStack 摄取端点,也可以运行 OpenTelemetry Collector,将链路写入现有 ClickHouse 数据库。
选择摄取路径
选择与所使用的 ClickHouse 服务相匹配的路径:
| 目标 | 路径 |
|---|---|
| ClickStack | 将链路发送到 ClickStack 提供的 OTLP/HTTP 端点。其内置 Collector 负责批处理、表结构管理和写入 ClickHouse。直接前往配置 AISIX 导出器。 |
| 现有 ClickHouse 数据库 | 部署本指南中的自定义 Collector 配置。Collector 接收 AISIX 的链路,并通过 ClickHouse 导出器写入数据库。 |
使用 ClickStack 时,请采用部署环境提供的完整链路端点和认证请求头。ClickStack 的 OTLP/HTTP 端点通常以 /v1/traces 结尾。自行部署的 ClickStack 可使用摄取密钥或 OIDC Bearer Token,具体取决于其内置 Collector 的配置。部署选项参见 ClickStack Collector 指南。
以下 Collector 部署步骤适用于尚未提供合适 OTLP 端点的现有 ClickHouse 数据库:
前提条件
部署自定义 Collector 路径前,请准备:
- 已连接网关的 AISIX Enterprise 或 AISIX Cloud 环境,或加载声明式
resources.yaml文件的 AISIX OSS 部署。 - 现有 ClickHouse 数据库及具有写入权限的账户。确定是否允许 Collector 创建数据库和表。
- 一次可通过网关成功完成的请求,用于验证。
- 网关到 Collector、Collector 到 ClickHouse 的网络连通性。
- Docker Compose,或网关所在 Kubernetes 命名空间的访问权限。
本指南固定使用 OpenTelemetry Collector Contrib 0.163.2。该发行版包含 ClickHouse 导出器;其 v0.163.0 组件参考将链路支持标为 beta。用于生产遥测前,请核查其稳定性和配 置。
配置 Collector
以下完整配置适用于新建的专用 Collector。如果已有兼容的 Collector,请将这些组件定义和流水线引用合入现有配置,保留无关组件,并按既有流程发布。
创建工作目录:
mkdir aisix-clickhouse
cd aisix-clickhouse
创建以下完整的 Collector 配置,并替换大写占位符:
extensions:
bearertokenauth:
token: 'COLLECTOR_TOKEN'
receivers:
otlp:
protocols:
http:
endpoint: '0.0.0.0:4318'
auth:
authenticator: bearertokenauth
exporters:
clickhouse:
endpoint: 'tcp://CLICKHOUSE_HOST:9000?dial_timeout=10s'
username: 'CLICKHOUSE_USER'
password: 'CLICKHOUSE_PASSWORD'
database: 'TARGET_DATABASE'
traces_table_name: 'TARGET_TRACES_TABLE'
create_schema: true
sending_queue:
num_consumers: 10
batch:
min_size: 5000
flush_timeout: 5s
service:
extensions: [bearertokenauth]
pipelines:
traces:
receivers: [otlp]
exporters: [clickhouse]
按下表替换占位符:
| 占位符或字段 | 值 |
|---|---|
COLLECTOR_TOKEN | 长随机 Token,例如使用 openssl rand -hex 32 生成。AISIX 导出器请求头应使用相同的值。 |
CLICKHOUSE_HOST 和端口 9000 | Collector 可访问的 ClickHouse 原生协议端点。使用数据库运维方提供的端口和 TLS 设置。 |
CLICKHOUSE_USER 和 CLICKHOUSE_PASSWORD | 可插入链路的 ClickHouse 账户;启用表结构创建时,还需具有创建目标数据库和表的权限。 |
TARGET_DATABASE | 存放链路表的数据库,例如 aisix。 |
TARGET_TRACES_TABLE | 链路表名,例如 otel_traces。 |
create_schema | 保持为 true,由导出器创建兼容的数据库和表。仅在数据库运维方已创建与此导出器版本兼容的表结构后,才设为 false。 |
此示例端点使用未启用 TLS 的 ClickHouse 原生协议。当流量经过不可信网络或数据库要求 TLS 时,请配置导出器的 TLS 设置。不要将凭据提交到源码仓库。
内部的 sending_queue.batch 配置遵循 ClickHouse 导出器当前的批处理建议。它会在五秒后刷新未满的批次,因此低流量验证无需等待凑满 5,000 行。不要为此流水线另加独立的 batch 处理器。
队列存放在内存中;Collector 重启时,待发送链路可能丢失。如需重启后仍保留队列,请通过存储扩展配置 sending_queue.storage,将该扩展加入 service.extensions,并把其目录挂载到持久化存储。
部署 Collector
下面两个示例都将 Collector 部署在网关旁边,并通过 otel-collector:4318 提供 OTLP/HTTP 接收器。
- Docker Compose
- Kubernetes
查找网关容器及其 Docker 网络:
docker ps --format 'table {{.Names}}\t{{.Image}}'
docker inspect GATEWAY_CONTAINER --format '{{json .NetworkSettings.Networks}}'
将 GATEWAY_CONTAINER 替换为 docker ps 返回的容器名。选择网关已连接的用户自定义网络。在 collector.yaml 旁创建以下文件,并将 GATEWAY_NETWORK 替换为该网络名:
services:
otel-collector:
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.163.2
command: ['--config=/etc/otelcol-contrib/config.yaml']
volumes:
- ./collector.yaml:/etc/otelcol-contrib/config.yaml:ro
networks: [gateway]
restart: unless-stopped
networks:
gateway:
external: true
name: GATEWAY_NETWORK
验证配置、启动 Collector 并查看日志:
docker compose run --rm otel-collector validate --config=/etc/otelcol-contrib/config.yaml
docker compose up -d
docker compose logs --tail=100 otel-collector
现在网关可以通过 http://otel-collector:4318/v1/traces 访问接收器。还需确认所选网络允许 Collector 访问 ClickHouse。
将 Collector 部署到网关所在命名空间,以便网关解析短 Service 名称。将下方所有 GATEWAY_NAMESPACE 替换为该命名空间。
从 collector.yaml 创建 Secret:
kubectl -n GATEWAY_NAMESPACE create secret generic otel-collector-config \
--from-file=collector.yaml=./collector.yaml
此 Secret 含有 ClickHouse 密码和 Collector Token。请使用集群既有的 Secret 和 RBAC 控制限制访问。
创建 Collector Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: otel-collector
namespace: GATEWAY_NAMESPACE
spec:
replicas: 1
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: collector
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.163.2
args: ['--config=/etc/otelcol-contrib/collector.yaml']
ports:
- name: otlp-http
containerPort: 4318
volumeMounts:
- name: config
mountPath: /etc/otelcol-contrib
readOnly: true
volumes:
- name: config
secret:
secretName: otel-collector-config
应用 Deployment 并暴露其接收器:
kubectl apply -f collector-deployment.yaml
kubectl -n GATEWAY_NAMESPACE expose deployment otel-collector \
--name=otel-collector --port=4318 --target-port=4318
kubectl -n GATEWAY_NAMESPACE rollout status deployment/otel-collector
kubectl -n GATEWAY_NAMESPACE logs deployment/otel-collector --tail=100
现在网关可以通过 http://otel-collector:4318/v1/traces 访问接收器。请在适用的 NetworkPolicy 中允许网关到 Collector、Collector 到 ClickHouse 的流量。
如果 Collector 位于其他命名空间,请使用带命名空间的 Service 地址。使用 OpenTelemetry Collector Helm Chart 时,应将这些组件设置合入其 config 值,而非 AISIX Chart 的 values。
这些部署示例只运行一个 Collector 副本,且没有设置资源限制。生产使用前,请根据链路数据量确定 Collector、队列的容量和可用性方案。
配置 AISIX 导出器
导出用于验证的网关 URL 和请求参数:
# AISIX_PROXY 不带末尾斜杠或端点路径
# 本地快速入门使用 http://127.0.0.1:3000
export AISIX_PROXY="YOUR_AISIX_GATEWAY_URL"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
export MODEL_ALIAS="YOUR_MODEL_ALIAS"
对于上文的自定义 Collector 部署,导出接收器 URL 和认证请求头:
export OTLP_ENDPOINT="http://otel-collector:4318/v1/traces"
export OTLP_AUTH_HEADER="Bearer YOUR_COLLECTOR_TOKEN"
使用 ClickStack 时,请将这些值替换为其完整的 OTLP/HTTP 链路端点,以及摄取配置要求的准确认证值。
网关接受指向任意主机的 http:// 和 https:// 导出器端点。1.7.0 及更早版本的网关只对 otel-collector 主机以及回环主机 localhost 和 127.0.0.1 接受 http://。使用 http:// 时,认证请求头和导出的遥测数据会以明文穿过网络。请只在可信网络中使用,尤其是在启用完整内容采集时。
按照配置 OTLP 导出器,通过 AISIX Enterprise、AISIX Cloud 或 AISIX OSS 创建导出器。在确认投递成功前,请将 sample_rate 保持为 1。导出器保存成功只能证明 AISIX 接受了配置。
验证投递
通过现有模型别名发送一次成功请求,并保存响应头:
curl -sS -D aisix-response.headers -o /dev/null \
-X POST "$AISIX_PROXY/v1/chat/completions" \
-H "Authorization: Bearer $AISIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_ALIAS}"'",
"messages": [{"role": "user", "content": "Reply with: ClickHouse trace check"}]
}'
export TEST_REQUEST_ID=$(awk 'tolower($1) == "x-aisix-request-id:" {id=$2; sub(/\r$/, "", id)} END {print id}' aisix-response.headers)
printf 'request ID: %s\n' "$TEST_REQUEST_ID"
如果请求 ID 为空,请先确认请求经过 AISIX 且成功,再检查导出路径。
使用 ClickStack 时,请在其链路视图中搜索该请求 ID。使用自定义 Collector 时,请至少等待五秒,让配置的未满批次刷新,然后查询目标表:
SELECT
Timestamp,
SpanName,
SpanKind,
TraceId,
SpanId,
ParentSpanId,
SpanAttributes['aisix.request_id'] AS request_id,
SpanAttributes['http.response.status_code'] AS status
FROM aisix.otel_traces
WHERE Timestamp >= now() - INTERVAL 15 MINUTE
AND SpanAttributes['aisix.request_id'] = 'YOUR_RETURNED_REQUEST_ID'
ORDER BY Timestamp ASC;
将请求 ID、数据库名和表名替换为实际值。一次到达上游的典型模型请求会产生一个 SERVER 跨度(Span)、一个逻辑 CLIENT 跨 度和一个尝试阶段的 CLIENT 跨度。其他结果可能产生更少的跨度,因此应以查到请求 ID 作为投递验证,不能依赖固定行数。
排查投递问题
使用 ClickStack 时,请检查其摄取状态或内置 Collector 日志,并确认 AISIX 端点及认证请求头与 ClickStack 提供的值一致。
使用自定义 Collector 时,请在修改配置前检查网关和 Collector 的日志:
- Docker Compose
- Kubernetes
将 GATEWAY_CONTAINER 替换为部署时使用的网关容器名:
docker compose ps
docker compose logs --since=10m otel-collector
docker logs --since=10m GATEWAY_CONTAINER
将 GATEWAY_NAMESPACE 替换为网关命名空间,将 AISIX_POD 替换为网关 Pod 名称:
kubectl -n GATEWAY_NAMESPACE get pods,svc,endpointslices
kubectl -n GATEWAY_NAMESPACE logs deployment/otel-collector --since=10m
kubectl -n GATEWAY_NAMESPACE logs AISIX_POD --since=10m
| 现象 | 检查项 |
|---|---|
接收器返回 401 或 403 | Collector Token、AISIX 的 Authorization 请求头,以及 Bearer 后是否有空格。 |
| DNS 或连接失败 | Service 名称、命名空间、Docker 网络、NetworkPolicy,以及 ClickHouse 主机和端口。 |
| 数据库认证、表结构或写入错误 | ClickHouse 凭据、权限、TLS 设置,以及表结构是否与固定的导出器版本兼容。 |
| 导出器已配置,但没有新行 | 目标网关、采样率、请求 ID、批处理延迟和查询时间范围。 |
| Collector 反复重启 | 固定镜像版本、未替换的占位符、配置语法、资源限制和工作负载日志。 |
对于 AISIX Enterprise 或 AISIX Cloud,环境的 Observability 视图中的导出器条目还会显示在线网关上报的投递健康状态。对于 AISIX OSS,请检查网关日志和目标端结果。
停止导出
通过创建导出器时使用的同一配置路径停用或移除 AISIX 导出器。使用 ClickStack 时,无需改动其内置 Collector。使用自定义 Collector 时,若共享 Collector 仍服务其他流水线,应保持运行。如果不再需要 ClickHouse 流水线,只通过常规 Collector 发布流程移除其接收器和导出器引用;现有数据库记录不受影响。
后续步骤
参见可观测性导出器,了解采样、内容采集和网关投递行为。使用 OTLP 链路参考了解链路结构和属性;ClickHouse 导出器参考介绍表结构、保留期、队列和数据库选项。