本文为您介绍 Apache APISIX opentelemetry
插件概念以及如何如何开启和部署 opentelemetry
插件。
Apache APISIX 是一个动态、实时、高性能的 API 网关,提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。作为 API 网关,Apache APISIX 不仅拥有众多实用的插件,而且支持插件动态变更和热插拔。
OpenTelemetry 是一个开源的遥测数据采集和处理系统,它不仅提供了各种 SDK 用于应用端遥测数据的收集和上报,以及数据收集端用于数据接收、加工和导出,还支持通过配置导出到任意一个或者多个已经适配 OpenTelemetry Exporter 的后端,比如 Jaeger、Zipkin、OpenCensus 等。您可以在 opentelemetry collector contrib 库中查看已经适配 OpenTelemetry Collector 的插件列表。
Apache APISIX opentelemetry
插件是基于 OpenTelemetry 原生标准(OTLP/HTTP)实现的 Tracing 数据采集,并通过 HTTP 协议发送至 OpenTelemetry Collector。该功能将在 Apache APISIX 2.13.0 版本中上线支持。
由于 OpenTelemetry 的 Agent/SDK 与后端实现无关,当应用集成了 OpenTelemetry 的 Agent/SDK 之后,用户能够在应用侧无感知的情况下轻松地、自由地变更可观测性后端服务,比如从 Zipkin 切换成 Jaeger。
opentelemetry
插件在 Apache APISIX 中集成了 OpenTelemetry Agent/SDK,可以实现采集被追踪的请求生成 trace 后转发到 OpenTelemetry Collector。
opentelemetry
插件位于上图中的 Agent 侧,但目前仅支持 trace
协议,还不支持 OpenTelemetry 的 logs
和 metrics
协议。
您需要在 conf/config.yaml
配置文件中启用 opentelemetry
插件并修改 collector
配置。
假设您已经完成 OpenTelemetry Collector 的部署,并且启用了 OTLP HTTP Receiver。
如果您未完成部署,可参考下一节的场景示例部分,完成 OpenTelemetry Collector 的部署。
其中 OTLP HTTP Receiver 的默认端口为4318
,collector
的地址为 OpenTelemetry Collector 的 HTTP Receiver 地址,相关字段可参考 Apache APISIX 官方文档。
plugins
... # 已经启用的其它插件
- opentelemetry
plugin_attr:
...
opentelemetry:
trace_id_source: x-request-id
resource:
service.name: APISIX
collector:
address: 127.0.0.1:4318 # OTLP HTTP Receiver 地址
request_timeout: 3
为了更方便的展示测试效果,示例中暂时将 sampler
设置为全采样,以确保每次请求都被追踪后产生 trace
数据,方便您在 Web UI 上查看 trace
的相关数据。您也可以根据实际情况,设置相关参数。
curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/get",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
您也可以通过 Apache APISIX Plugins 功能启用 opentelemetry
插件。完成全局配置后,您仍然需要创建路由,否则将无法进行测试。
curl 'http://127.0.0.1:9080/apisix/admin/global_rules/1' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '{
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
}
}'
additional_attributes
为 Span 自定义标签关于 sampler
和 additional_attributes
的配置您可以参考 Apache APISIX 官方文档,其中 additional_attributes
是一系列的 Key:Value
键值对,您可以使用它为 Span 自定义标签,并且可以跟随 Span 在 Web UI 上展示。通过 additional_attributes
为某个路由的 Span 增加 route_id
和 http_x-custom-ot-key
,可以参考如下配置:
curl http://127.0.0.1:9080/apisix/admin/routes/1001 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/put",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
},
"additional_attributes":[
"route_id",
"http_x-custom-ot-key"
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
您可以通过以上三种方式中的任意一种方式启用 opentelemetry
,以下示例使用方式三的方法创建路由,创建成功后,您可以参考如下命令访问路由:
curl -X PUT -H `x-custom-ot-key: test-ot-val` http://127.0.0.1:9080/put
访问成功之后,您可以在 Jaeger UI 中看到类似如下图所示 /put 的 Span 详情,并可以看到 Tags 列表中展示了路由中自定义的 tag:http_x-custom-ot-key
和 route_id
。
您需要注意,additional_attributes
配置的设定是从 Apache APISIX 和 Nginx 变量取值作为 attribute
的值,因此 additional_attributes
必须是 Apache APISIX 或者 Nginx 的有效变量。其中也包括 HTTP Header,但是在取 http_header
时,需要添加 http_
作为变量名的前缀。如果变量不存在,就不会展示这个 tag
了。
本场景示例通过简单修改 OpenTelemetry Collector 官方示例部署 Collector、Jaeger 和 Zipkin 作为后端服务,并且启动两个示例应用程序(Client 和 Server),其中 Server 提供了一个 HTTP 服务,而 Client 会循环调用 Server 提供的 HTTP 接口,从而产生包括两个 Span 的调用链。
以下使用 docker-compose
作为示例,其它部署可以参考 OpenTelemetry 官方文档。
您可以参考如下命令部署:
git clone https://github.com/open-telemetry/opentelemetry-collector-contrib.git
cd opentelemetry-collector-contrib/examples/demo
docker-compose up -d
在浏览器中输入 http://127.0.0.1:16886
(Jaeger UI)或者 http://127.0.0.1:9411/zipkin
(Zipkin UI),如果可以正常访问,则表示部署成功。
下图为访问成功示例:
引入 Apache APISIX 服务,最终应用的拓扑如下图所示:
Trace 数据上报流程如下。其中由于 Apache APISIX 是单独部署的,并不在 docker-compose
的网络内,所以 Apache APISIX 是通过本地映射的端口(即 127.0.0.1:4138
)访问到 OpenTelemetery Collector 的 OTLP HTTP Receiver 的。
您需要确保已经启用 opentelemetry
插件,并重新加载 Apache APISIX。
opentelemetry
插件进行采样:curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/hello",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on",
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:7080": 1
}
}
}'
./examples/demo/otel-collector-config.yaml
文件,并添加 OTLP HTTP Receiver,如下所示:receivers:
otlp:
protocols:
grpc:
http:${ip:port} # 添加 OTLP HTTP Receiver,默认端口为 4318
docker-compose.yaml
。您需要修改配置文件,把 Client 调用 Server 的接口地址修改为 Apache APISIX 的地址,将 OTLP HTTP Receiver 和 Server 服务的端口映射到本地。
以下示例是修改配置后完整的 docker-compose.yaml
:
version: "2"
services:
# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # jaeger ui 的端口
- "14268"
- "14250"
# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- "9411:9411"
# Collector
otel-collector:
image: ${OTELCOL_IMG}
command: ["--config=/etc/otel-collector-config.yaml", "${OTELCOL_ARGS}"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "1888:1888" # pprof extension
- "8888:8888" # Prometheus metrics exposed by the collector
- "8889:8889" # Prometheus exporter metrics
- "13133:13133" # health_check extension
- "4317" # OTLP gRPC receiver
- "4318:4318" # 添加 OTLP HTTP Receiver 端口映射
- "55670:55679" # zpages extension
depends_on:
- jaeger-all-in-one
- zipkin-all-in-one
demo-client:
build:
dockerfile: Dockerfile
context: ./client
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317
- DEMO_SERVER_ENDPOINT=http://172.17.0.1:9080/hello # APISIX 的地址
depends_on:
- demo-server
demo-server:
build:
dockerfile: Dockerfile
context: ./server
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317
ports:
- "7080:7080" # 将 Server 端口映射到宿主机
depends_on:
- otel-collector
prometheus:
container_name: prometheus
image: prom/prometheus:latest
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
需要注意,demo-client.environment.DEMO_SERVER_ENDPOINT
处需要改为您的 Apache APISIX 地址,且保证在容器内可以正常访问。
当然,您也可以通过 docekr-compose.yaml
部署 Apache APISIX ,具体可以参考 Apache APISIX 官方文档。
重新部署完成后,访问 Jaeger UI 或者 Zipkin UI 即可看到 Trace 中包含了 APISIX 的 Span,如下图:
如果您暂时不需要某个路由的 Trace 采集,则仅需修改路由配置,将配置中的 plugins
下的 opentelemetry
相关配置删除即可。
如果您是通过绑定 Global Rules 全局启用的,则只能删除 opentelemetry
全局插件的配置。得益于 Apache APISIX 的动态化优势,开启关闭插件的过程都不需要重启 Apache APISIX,十分方便。
Apache APISIX 在集成 OpenTelemetery 之后,借助 OpenTelemetry 丰富的插件能够与市场上大部分主流的 Trace 系统轻松实现对接。此外,Apache APISIX 也实现了 SkyWalking 和 Zipkin 原生标准协议插件,也在积极与各大社区合作打造更加强大的生态。
Apache APISIX 项目目前正在开发其他插件以支持集成更多服务,如果您对此有兴趣,您可以通过 GitHub Discussions 发起讨论,或通过邮件列表进行交流.