LabHub
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

SDK 配置与资源属性

在 LabHub 中继续学习

目标

通过环境变量配置 SDK,按照语义约定确定资源属性,并在 Kubernetes 中使用 Downward API 注入实例标识符。最后亲自创建一个检查 span 名称基数的 linter。

为什么重要

可观测性埋点中最难撤销的决定是资源属性。代码随时可以修改,但一旦更改 service.name,仪表板、告警、服务图以及与历史数据的关联都会全部中断。因此,在增加 span 之前必须先确定这些属性。名称约定出于同样原因非常重要。deployment.environmentdeployment.environment.name 在人看来相同,但对系统而言是两个完全不同的属性,而仪表板变量只会读取其中一个。span 名称也是如此。如果名称中混入 ID,后端的聚合视图会彻底失效,而这种事故不会在部署后立即发现,往往在几周后以“服务图很奇怪”的形式出现。因此,必须由 CI 阻止,而不是依赖人的记忆。

步骤

  1. 创建 /root/otca-sdk/otel.env,写入 OTEL_SERVICE_NAME=checkout-apiOTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317OTEL_EXPORTER_OTLP_PROTOCOL=grpc。每行一项,格式为 키=값
  2. 在同一文件中添加 OTEL_RESOURCE_ATTRIBUTES。值是用逗号连接的 service.version=2.7.1deployment.environment.name=prodservice.namespace=commerce。不要使用旧名称 deployment.environment
  3. 在同一文件中添加 OTEL_TRACES_SAMPLER=parentbased_traceidratioOTEL_TRACES_SAMPLER_ARG=0.1OTEL_PROPAGATORS=tracecontext,baggage
  4. 在同一文件中添加四个上限:OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=64OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=2048OTEL_BSP_MAX_QUEUE_SIZE=4096OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512
  5. /root/otca-sdk/deployment.yaml 中编写 Deployment。metadata.name: checkout-apimetadata.namespace: otca-sdk。在第一个容器的 env 中加入 POD_NAME(fieldRef metadata.name)、POD_NAMESPACE(fieldRef metadata.namespace)、OTEL_SERVICE_NAME=checkout-apiOTEL_EXPORTER_OTLP_ENDPOINT(包含 4317)以及 OTEL_RESOURCE_ATTRIBUTES;其值中必须包含 deployment.environment.name=prodservice.instance.id=$(POD_NAME)k8s.namespace.name=$(POD_NAMESPACE)
  6. 创建命名空间 otca-sdk,并将第 5 步的清单应用到集群。
  7. /root/otca-sdk/span-names.txt 中写入至少 6 行 span 名称。其中至少 4 行必须像 GET /... 一样以 HTTP 方法开头,至少 3 行必须包含 :id 占位符。不能有任何一行包含连续三个或更多数字或 UUID。
  8. 编写 /root/otca-sdk/lint-span-names.sh。如果第一个参数指定的文件中包含连续三个或更多数字或 UUID 形式,就输出对应行并以非零代码退出;否则以 0 退出。

参考

服务名称与 endpoint

创建 /root/otca-sdk/otel.env,写入 OTEL_SERVICE_NAME=checkout-apiOTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317OTEL_EXPORTER_OTLP_PROTOCOL=grpc。每行一项,格式为 키=값

只使用环境变量即可控制 SDK。因此,埋点配置位于部署清单而非代码中,更改 endpoint 无需代码审查。端口和协议必须正确配对。

确定资源属性

在同一文件中添加 OTEL_RESOURCE_ATTRIBUTES。值是用逗号连接的 service.version=2.7.1deployment.environment.name=prodservice.namespace=commerce。不要使用旧名称 deployment.environment

资源属性会附加到此进程发出的所有信号上。多个属性用逗号连接,每个都采用键=值形式。环境属性名称在近期约定中发生了变化,请注意不要使用旧名称。

Sampler 与 Propagator

在同一文件中添加 OTEL_TRACES_SAMPLER=parentbased_traceidratioOTEL_TRACES_SAMPLER_ARG=0.1OTEL_PROPAGATORS=tracecontext,baggage

Sampler 名称中必须带有 parentbased,才能遵循父级决定。否则各服务会独立进行概率判断,导致 trace 在中途被截断。可以用逗号指定多个 Propagator。

span 大小与队列上限

在同一文件中添加四个上限:OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=64OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT=2048OTEL_BSP_MAX_QUEUE_SIZE=4096OTEL_BSP_MAX_EXPORT_BATCH_SIZE=512

属性数量有默认上限,但值长度没有。如果整个请求正文都被写入,一个 span 可能达到数百 KB。还要同时确定 Batch Span Processor 的队列大小和批次大小。

使用 Downward API 注入实例标识符

/root/otca-sdk/deployment.yaml 中编写 Deployment。metadata.name: checkout-apimetadata.namespace: otca-sdk。在第一个容器的 env 中加入 POD_NAME(fieldRef metadata.name)、POD_NAMESPACE(fieldRef metadata.namespace)、OTEL_SERVICE_NAME=checkout-apiOTEL_EXPORTER_OTLP_ENDPOINT(包含 4317)以及 OTEL_RESOURCE_ATTRIBUTES;其值中必须包含 deployment.environment.name=prodservice.instance.id=$(POD_NAME)k8s.namespace.name=$(POD_NAMESPACE)

如果硬编码 Pod 名称,每次重启后都会留下错误值。通过 fieldRef 将 metadata.name 和 metadata.namespace 接收到环境变量中,再在另一个环境变量中用括号表示法引用,kubelet 就会进行替换。多行值使用折叠块更易阅读。

应用到集群

创建命名空间 otca-sdk,并将第 5 步的清单应用到集群。

先创建命名空间,再应用清单。评分会读取实际进入集群的 Pod 模板,因此只修改文件而不应用就无法通过。

低基数 span 名称列表

/root/otca-sdk/span-names.txt 中写入至少 6 行 span 名称。其中至少 4 行必须像 GET /... 一样以 HTTP 方法开头,至少 3 行必须包含 :id 占位符。不能有任何一行包含连续三个或更多数字或 UUID。

后端按 span 名称分组,生成延迟统计和服务图。如果名称中包含订单号或 UUID,分组数量会增加到与请求数相同。路由应使用模板,具体值则作为属性发送。

span 名称 linter

编写 /root/otca-sdk/lint-span-names.sh。如果第一个参数指定的文件中包含连续三个或更多数字或 UUID 形式,就输出对应行并以非零代码退出;否则以 0 退出。

脚本通过第一个参数接收列表文件。如果其中包含连续三个或更多数字或 UUID 形式,输出该行并以失败结束即可。前一步创建的列表必须通过。