从go语言出发,搭建多语言云原生场景下全链路观测体系
一、方案背景
在公司内部devops平台的微服务化改造过程中,我们遇到了典型的分布式系统观测难题:服务间调用链路复杂、性能瓶颈难以定位、故障排查效率低下。特别是在生产环境出现问题时,往往需要花费大量时间在各个服务的日志中寻找蛛丝马迹。
经过前期的技术调研和实际踩坑,我们最终确定了基于 OpenTelemetry Collector + Kubernetes Operator + 阿里云 SLS 的观测平台解决方案。这套方案的核心目标是:让开发团队能够快速定位问题,让运维团队能够主动发现问题,让业务团队能够洞察系统性能对用户体验的影响。
二、技术选型深度对比
2.1 阿里云链路追踪实战踩坑记录
在实际接入阿里云链路追踪的过程中,我们遇到了几个关键问题:
数据闭环问题
-
问题描述:阿里云链路追踪的数据完全封闭在云平台内部,外部系统无法获取原始数据
-
影响范围:无法进行定制化数据分析、无法与现有监控体系集成、难以实现跨平台数据关联
-
业务痛点:当我们需要基于链路数据做业务分析或告警定制时,完全受限于阿里云提供的功能
功能局限性问题
-
接口筛选限制:无法按照
kind:server
进行接口列表筛选,导致客户端调用和服务端处理混在一起 -
告警配置受限:告警规则无法基于 span 的 kind 属性进行精确配置
-
环境隔离混乱:通过标签区分环境导致全局拓扑图极为混乱,影响问题排查效率
技术架构分析
阿里云链路追踪的本质
-
底层基于 SkyWalking 实现
-
SkyWalking 本身是 OpenTracing 的增强版,包含 Trace 和 Metrics 数据
-
但并非标准的 OpenTelemetry 协议,缺乏标准化支撑
核心问题根源
-
云产品的数据闭环特性,基本断绝了定制化扩展的可能性
-
非标准协议导致后期 Metrics 定制化扩展时无标准可循
-
强耦合的产品设计限制了技术栈的灵活性
2.2 链路追踪方案对比
基于实际使用经验,我们对主流链路追踪方案进行了深入对比:
方案 | 标准支持 | 运维成本 | 存储后端 | 数据消费 | 厂商绑定 | 推荐度 |
---|---|---|---|---|---|---|
SkyWalking | 自有协议 | 高(需自建ES集群) | Elasticsearch | 受限 | 中等 | ❌ |
Jaeger | OpenTracing/OTel | 高(需自建存储) | Cassandra/ES | 开放 | 低 | ⚠️ |
阿里云链路追踪 | 基于SkyWalking | 低 | 托管 | 封闭 | 高 | ❌ |
阿里云SLS | 完整OTel支持 | 低 | 托管 | 开放 | 低 | ✅ |
2.3 为什么不选择 SkyWalking?
运维成本过高
存储后端复杂性:
# SkyWalking 典型部署架构
SkyWalking OAP Server:- 需要 Elasticsearch 集群(至少3节点)- 需要配置索引模板和生命周期策略- 需要监控 ES 集群健康状态- 数据量大时查询性能下降明显Elasticsearch 集群:resources:requests:memory: "4Gi" # 每节点最少4GB内存cpu: "2"limits:memory: "8Gi" # 生产环境建议8GB+cpu: "4"
成本分析对比:
组件 | SkyWalking方案 | SLS方案 |
---|---|---|
计算资源 | OAP Server: 2C4G × 2 | 无需自建 |
存储资源 | ES集群: 4C8G × 3 | 按量付费 |
运维人力 | 需要ES人员运维 | 无需专门运维 |
月成本估算 | ¥3000-5000 | ¥800-1500 |
技术标准化问题
协议兼容性:
// SkyWalking 使用自有协议
type SegmentObject struct {TraceSegmentId string `json:"traceSegmentId"`// 非标准 OpenTelemetry 格式
}// OpenTelemetry 标准格式
type Span struct {TraceId []byte `json:"trace_id"`SpanId []byte `json:"span_id"`// 遵循 OTLP 协议标准
}
-
厂商锁定风险:SkyWalking 使用自有数据格式,迁移成本高
-
生态兼容性:与 OpenTelemetry 生态集成需要额外适配
-
标准化程度:不符合 CNCF 推荐的 OpenTelemetry 标准
2.4 为什么选择 OpenTelemetry + 阿里云 SLS?
基于前面踩坑经验的总结,我们最终选择了 OpenTelemetry + 阿里云 SLS 的技术方案:
OpenTelemetry 的标准化价值
在经历了阿里云链路追踪的数据闭环问题后,我们深刻认识到标准化的重要性:
# OpenTelemetry 配置(标准化)
receivers:otlp:protocols:grpc:endpoint: "0.0.0.0:55680"http:endpoint: "0.0.0.0:55681"exporters:# 可以轻松切换到任何支持 OTLP 的后端otlp/sls:endpoint: "https://sls-endpoint"# 或者切换到其他厂商otlp/jaeger:endpoint: "http://jaeger:14250"
实际项目中的迁移便利性:
-
从阿里云链路追踪迁移时,应用代码完全不需要修改
-
我们可以同时导出到多个后端,在迁移过程中进行数据对比验证
-
基于 CNCF 标准,避免了再次踩坑的风险
成本效益分析
在实际项目预算评估中,我们发现成本差异非常明显:
真实成本对比(基于我们的实际使用量):
# 月处理约100GB Trace数据的成本对比
SkyWalking 自建方案:
- ECS费用: ¥2400 (OAP Server + ES集群)
- 存储费用: ¥800 (高性能SSD)
- 运维成本: ¥2000 (需要专门的ES运维)
- 监控告警: ¥200 (额外的监控组件)
总计: ¥5400/月阿里云 SLS 方案:
- 存储费用: ¥600 (100GB数据)
- 查询费用: ¥300 (日常查询)
- 运维成本: ¥0 (托管服务)
总计: ¥900/月实际节省: 83% (¥4500/月)
这个成本差异在项目立项时起到了决定性作用,特别是考虑到我们团队缺乏 Elasticsearch 专业运维经验的情况下。
数据开放性解决核心痛点
这是我们选择 SLS 而不是阿里云链路追踪的关键原因:
实时数据消费能力:
# SLS 支持实时数据消费,这是我们实际在用的代码
from aliyun.log import LogClient# 实时消费 Trace 数据进行业务分析
client = LogClient(endpoint, access_key_id, access_key_secret)
response = client.pull_logs(project, logstore, shard_id, cursor)# 我们基于这个能力实现了自定义的性能告警
for log in response.get_logs():# 检测慢查询if log.get('duration') > 2000 and 'mysql' in log.get('operation_name', ''):send_slow_query_alert(log)# 检测错误率异常if log.get('status_code') == 'ERROR':update_error_metrics(log)
解决的实际问题:
-
自定义告警:我们可以基于业务逻辑设置精确的告警规则,而不是被限制在云产品的固定功能中
-
数据关联分析:能够将链路数据与业务指标进行关联,实现更深层次的业务洞察
-
多维度消费:同一份数据可以同时供给 Grafana、自建告警系统、数据分析平台使用
2.5 最终技术架构确认
基于以上分析,我们确定的技术架构为:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 应用服务 │ │ OpenTelemetry │ │ 数据存储 │
│ │ │ Collector │ │ │
│ ┌─────────────┐ │ │ (DaemonSet) │ │ ┌─────────────┐ │
│ │ Metrics │─┼────┼──────────────────┼────┼→│ Prometheus │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
│ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │
│ │ Traces │─┼────┼──────────────────┼────┼→│ 阿里云 SLS │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
│ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │
│ │ Logs │─┼────┼──────────────────┼────┼→│业务LogStore │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
└─────────────────┘ └──────────────────┘ └─────────────────┘↓┌──────────────────┐│ Grafana ││ (统一展示) ││ ││ • Prometheus数据 ││ • SLS Trace数据 ││ • 日志关联查询 │└──────────────────┘
架构特点:
-
Metrics:通过 Prometheus 直接采集和存储,利用其成熟的生态
-
Traces:通过 OpenTelemetry Collector 上报到阿里云 SLS,享受托管服务优势
-
Logs:保持现有业务 LogStore 不变,避免业务改造
-
展示:统一在 Grafana 中展示所有观测数据,实现一站式监控
核心优势:
-
成本最优:相比自建 SkyWalking 节省 80%+ 成本
-
标准开放:基于 OpenTelemetry 标准,避免厂商锁定
-
运维简单:无需维护复杂的存储集群
-
扩展性强:支持数据实时消费和自定义分析
-
业务无感:日志系统保持不变,减少业务改造风险
三、核心概念解析
3.1 OpenTelemetry Collector DaemonSet 架构优势
为什么选择 DaemonSet 部署模式?
1. 网络开销最小化
传统的集中式 Collector 部署方式存在以下问题:
-
跨节点网络传输:应用数据需要通过 K8s Service 或 Ingress 路由到远程 Collector,增加网络跳数
-
网络延迟累积:数据传输路径:应用 → kube-proxy → Service → 远程节点 → Collector
-
带宽竞争:所有节点的观测数据汇聚到少数几个 Collector 实例,容易形成网络瓶颈
DaemonSet 模式的网络优势:
传统模式:App Pod → 远程 OAP SERVER Pod (跨节点网络,需要nat网关)DaemonSet:App Pod → DaemonSet:55680 (同集群同节点网络栈,不走nat网关)
-
本地通信:应用直接通过
DaemonSet:55680
与同节点的 Collector 通信,避免跨节点网络传输 -
零延迟:同节点网络延迟接近 0,大幅降低观测数据的传输延迟
-
带宽节省:节点内通信不占用集群网络带宽,避免对业务流量的影响
-
高可用性:每个节点独立的 Collector 实例,单点故障不影响其他节点
2. 资源利用优化
# DaemonSet 资源配置示例
resources:requests:memory: "128Mi" # 每节点固定资源消耗cpu: "100m"limits:memory: "256Mi" # 可预测的资源上限cpu: "200m"
-
资源分散:Collector 资源消耗分散到各个节点,避免单节点资源热点
-
线性扩展:随着节点数量增加,Collector 处理能力线性扩展
-
故障隔离:单个节点的 Collector 故障不影响其他节点的数据收集
3. 配置管理简化
# 统一的 ConfigMap 配置
apiVersion: v1
kind: ConfigMap
metadata:name: otel-collector-config
data:config.yaml: |receivers:otlp:protocols:grpc:endpoint: "0.0.0.0:55680" # 所有节点统一配置
-
配置一致性:所有节点使用相同的 Collector 配置,简化运维管理
-
热更新支持:通过 ConfigMap 更新可以同时影响所有节点的 Collector
-
版本管理:DaemonSet 确保所有节点运行相同版本的 Collector
3.2 Kubernetes Operator 无侵入式改造原理
为什么选择 Operator 模式?
1. 声明式配置管理
传统的观测接入方式存在以下问题:
-
手动配置:需要开发人员手动修改每个应用的 Deployment 配置
-
配置分散:观测配置散布在各个应用的部署文件中,难以统一管理
-
人为错误:手动配置容易出现拼写错误、配置不一致等问题
-
维护成本高:配置变更需要逐个应用修改,工作量大
Operator 的声明式优势:
# 应用只需添加标签,无需修改容器配置
metadata:labels:odyssey-apm-enable: "true" # 声明:我需要观测odyssey-apm-language: "java" # 声明:我是 Java 应用odyssey-apm-sampling-rate: "0.3" # 声明:30% 采样率
-
标签驱动:通过标签声明观测需求,Operator 自动处理具体实现
-
配置集中:所有观测逻辑集中在 Operator 中,便于统一管理和升级
-
自动化执行:标签变更自动触发配置更新,无需人工干预
2. 无侵入式注入机制
Java 应用无侵入原理:
// Operator 自动注入的环境变量
javaToolOptions := fmt.Sprintf("-javaagent:/usr/local/agent/opentelemetry.jar " +"-Dotel.service.name=%s " +"-Dotel.exporter.otlp.traces.endpoint=http://DaemonSet:55680",serviceName)container.Env = append(container.Env, corev1.EnvVar{Name: "JAVA_TOOL_OPTIONS",Value: javaToolOptions,
})
-
JavaAgent 机制:利用 JVM 的
-javaagent
参数在类加载时进行字节码增强 -
零代码改动:应用代码完全不需要修改,只需在镜像中包含 OpenTelemetry JavaAgent
-
自动埋点:JavaAgent 自动识别并埋点常见框架(Spring、MyBatis、Redis 等)
-
运行时注入:通过环境变量在容器启动时注入配置,不影响镜像构建
Golang 应用最小侵入原理:
// Operator 注入的环境变量
envVars := map[string]string{"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "http://DaemonSet:55680","OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "grpc","OTEL_SERVICE_NAME": serviceName,"OTEL_TRACES_SAMPLER": "parentbased_traceidratio","OTEL_TRACES_SAMPLER_ARG": samplingRate,
}
-
环境变量配置:通过标准的 OpenTelemetry 环境变量进行配置
-
SDK 自动初始化:OpenTelemetry Go SDK 自动读取环境变量并初始化
-
最小代码改动:只需在应用启动时调用 SDK 初始化函数
-
标准化接入:遵循 OpenTelemetry 标准,便于后续迁移和升级
3. 动态配置管理
实时监听机制:
// Operator 的 Reconcile 循环
func (r *ObserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {// 1. 监听 Deployment 变化事件var deployment appsv1.Deploymentif err := r.Get(ctx, req.NamespacedName, &deployment); err != nil {return ctrl.Result{}, client.IgnoreNotFound(err)}// 2. 检查观测标签if apmEnable, exists := deployment.Labels["odyssey-apm-enable"]; exists && apmEnable == "true" {// 3. 自动注入观测配置r.injectObservabilityConfig(&deployment)} else {// 4. 自动清理观测配置r.removeObservabilityConfig(&deployment)}return ctrl.Result{}, nil
}
-
事件驱动:基于 K8s API 的 Watch 机制,实时响应 Deployment 变化
-
自动同步:标签添加/删除自动触发配置注入/清理,保持状态一致
-
批量管理:支持批量操作,可以同时管理多个应用的观测配置
-
版本控制:配置变更通过 K8s 的版本控制机制进行管理
4. 运维友好性
统一管理界面:
# 查看所有启用观测的应用
kubectl get deployments -l odyssey-apm-enable=true# 批量启用观测
kubectl label deployments -l app.type=microservice odyssey-apm-enable=true# 查看 Operator 运行状态
kubectl logs -f deployment/odyssey-obser-operator
-
可视化管理:通过 kubectl 命令或 K8s Dashboard 可视化管理观测配置
-
批量操作:支持基于标签选择器的批量配置操作
-
审计日志:所有配置变更都有完整的审计日志
-
故障自愈:Operator 持续监控并自动修复配置漂移
3.3 架构优势总结
方面 | 传统方式 | Operator + DaemonSet 方式 |
---|---|---|
网络开销 | 跨节点传输,延迟高 | 本地通信,零延迟 |
配置管理 | 手动分散配置 | 自动化集中管理 |
代码侵入 | 需要修改应用代码 | Java 零侵入,Go 最小侵入 |
运维复杂度 | 高,需要逐个配置 | 低,标签驱动自动化 |
扩展性 | 集中式瓶颈 | 线性扩展 |
故障影响 | 单点故障影响全局 | 故障隔离,影响最小 |
资源利用 | 资源热点 | 资源分散,利用率高 |
核心特性
-
无侵入接入:Java 应用通过 JavaAgent 零代码改动,Golang 应用通过环境变量配置
-
自动化管理:通过 K8s Operator 自动监听 Deployment 变化,动态注入观测配置
-
统一数据出口:所有观测数据统一上报至阿里云 SLS,支持多维度分析
-
灵活采样控制:支持通过标签配置链路采样率,平衡性能与观测精度
-
多平台支持:既支持奥德赛 CICD 平台一键开启,也支持独立 K8s 环境手动配置
四、架构设计
4.1 整体架构图
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 应用服务 │ │ OpenTelemetry │ │ 阿里云 SLS │
│ │ │ Collector │ │ │
│ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │
│ │ Java App │─┼────┼─► gRPC:55680 ─┼────┼─► Trace Store │ │
│ │ (JavaAgent) │ │ │ HTTP:55681 │ │ │ │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │
│ │ Golang App │─┼────┼─► OTLP Protocol ─┼────┼─► Metrics │ │
│ │ (SDK) │ │ │ │ │ │ Store │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
└─────────────────┘ └──────────────────┘ └─────────────────┘▲ ▲ ││ │ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ K8s Operator │ │ DaemonSet │ │ 观测平台 │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ Deployment │ │ │ │ OTel │ │ │ │ SLS 控制台 │ │
│ │ Watcher │ │ │ │ Collector │ │ │ │ │ │
│ └─────────────┘ │ │ │ Pod │ │ │ └─────────────┘ │
│ │ │ └─────────────┘ │ │ │
│ ┌─────────────┐ │ │ │ │ ┌─────────────┐ │
│ │ Env Var │ │ │ │ │ │ Grafana + │ │
│ │ Injector │ │ │ │ │ │ Jaeger UI │ │
│ └─────────────┘ │ │ │ │ └─────────────┘ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
4.2 数据流向
应用 Pod → OpenTelemetry Collector (DaemonSet) → 阿里云 SLS↑ ↑
Operator 注入配置 本地 localhost:55680
-
配置注入:Operator 监听 Deployment 变化,自动注入观测配置
-
数据生成:应用启动时自动初始化 OpenTelemetry SDK
-
本地收集:应用通过 localhost:55680 将数据发送到同节点 Collector
-
数据处理:Collector 对数据进行批处理、采样、格式转换
-
远程上报:Collector 将处理后的数据上报到阿里云 SLS
4.3 组件职责
组件 | 职责 | 部署方式 |
---|---|---|
OpenTelemetry Collector | 接收应用上报的 OTLP 数据,转发至 SLS | DaemonSet(每个节点一个实例) |
K8s Operator | 监听 Deployment 变化,自动注入观测配置 | Deployment(集群级单实例) |
应用服务 | 通过 Agent 或 SDK 上报观测数据 | 现有 Deployment |
阿里云 SLS | 存储和分析观测数据 | 云服务 |
五、核心组件实现
5.1 OpenTelemetry Collector
配置说明
基于 otelcol-contrib
构建,配置文件 /tools/obser/config.yaml
:
receivers:otlp:protocols:grpc:endpoint: "0.0.0.0:55680" # 接收 gRPC 协议数据http:endpoint: "0.0.0.0:55681" # 接收 HTTP 协议数据exporters:alibabacloud_logservice/sls-trace:endpoint: "sre-observability-monitor.cn-shanghai.log.aliyuncs.com"project: "sre-observability-monitor"logstore: "odyssey-stage-traces"access_key_id: "${SLS_ACCESS_KEY_ID}"access_key_secret: "${SLS_ACCESS_KEY_SECRET}"service:pipelines:traces:receivers: [otlp]exporters: [alibabacloud_logservice/sls-trace]
部署清单
apiVersion: apps/v1
kind: DaemonSet
metadata:name: odyssey-otel-collectornamespace: odyssey-observability
spec:selector:matchLabels:app: odyssey-otel-collectortemplate:metadata:labels:app: odyssey-otel-collectorspec:containers:- name: otel-collectorimage: {otel collector的docker镜像}ports:- containerPort: 55680name: grpc- containerPort: 55681name: httpenv:- name: SLS_ACCESS_KEY_IDvalueFrom:secretKeyRef:name: sls-credentialskey: access-key-id- name: SLS_ACCESS_KEY_SECRETvalueFrom:secretKeyRef:name: sls-credentialskey: access-key-secretresources:requests:memory: "128Mi"cpu: "100m"limits:memory: "256Mi"cpu: "200m"hostNetwork: true # 使用主机网络,便于应用访问
5.2 Kubernetes Operator
功能特性
基于 /operator/obser/main.go
实现的 K8s Operator,具备以下能力:
-
自动发现:监听集群内所有 Deployment 的创建、更新、删除事件
-
标签驱动:根据 Deployment 标签自动判断是否需要注入观测配置
-
多语言支持:支持 Java(JavaAgent)和 Golang(SDK)两种接入方式
-
采样率控制:支持通过标签配置链路采样率
-
服务名映射:优先使用 Pod 的
app
标签作为服务名
标签配置规范
标签名 | 值 | 说明 |
---|---|---|
odyssey-apm-enable | "true" | 启用观测功能 |
odyssey-apm-language | "java" 或 "golang" | 应用语言类型,默认 java |
odyssey-apm-sampling-rate | "0.1" ~ "1.0" | 链路采样率,默认 1.0 (全采样) |
环境变量注入逻辑
Java 应用:
JAVA_TOOL_OPTIONS="-javaagent:/usr/local/agent/opentelemetry.jar \-Dotel.service.name=${SERVICE_NAME} \-Dotel.exporter.otlp.traces.endpoint=http://localhost:55680 \-Dotel.exporter.otlp.traces.protocol=grpc \-Dotel.exporter.otlp.traces.insecure=true \-Dotel.metrics.exporter=none \-Dotel.logs.exporter=none \-Dotel.traces.sampler=parentbased_traceidratio \-Dotel.traces.sampler.arg=${SAMPLING_RATE}"
Golang 应用:
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:55680"
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL="grpc"
OTEL_SERVICE_NAME="${SERVICE_NAME}"
OTEL_TRACES_SAMPLER="parentbased_traceidratio"
OTEL_TRACES_SAMPLER_ARG="${SAMPLING_RATE}"
5.3 应用接入方式
Java 应用(无侵入)
-
镜像准备:在应用镜像中预置 OpenTelemetry JavaAgent``dockerfile# 在应用 Dockerfile 中添加ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar /usr/local/agent/opentelemetry.jar
\
-
标签配置:在 Deployment 上添加观测标签``yamlmetadata:labels:odyssey-apm-enable: "true"odyssey-apm-language: "java"odyssey-apm-sampling-rate: “0.3” # 30% 采样率
\
-
自动生效:Operator 自动注入
JAVA_TOOL_OPTIONS
环境变量,应用重启后生效
Golang 应用(otel动态插桩)
-
编译代理:使用otel go agent完成编译改造,只需要加上前缀 otel即可
-
标签配置:在 Deployment 上添加观测标签``yamlmetadata:labels:odyssey-apm-enable: "true"odyssey-apm-language: "golang"odyssey-apm-sampling-rate: “0.5” # 50% 采样率
\
-
自动生效:Operator 自动注入 OTEL 相关环境变量,应用重启后生效
六、部署实施方案
6.1 环境准备
命名空间创建
kubectl create namespace odyssey-observability
SLS 凭证配置
kubectl create secret generic sls-credentials \--from-literal=access-key-id="LTAI5t7snKaMwG2RjVAdFv8H" \--from-literal=access-key-secret="4t1E90OJyWhrYfoRtbwsuLQxiJmueN" \-n odyssey-observability
6.2 组件部署顺序
-
部署 OpenTelemetry Collector DaemonSet``bashkubectl apply -f otel-collector-daemonset.yaml
\
-
部署 K8s Operator``bashkubectl apply -f odyssey-obser-operator.yaml
\
-
验证部署状态``bashkubectl get pods -n odyssey-observabilitykubectl logs -f deployment/odyssey-obser-operator -n odyssey-observability
\
6.3 应用接入流程
devops 平台CICD 平台接入
-
平台配置:在devops CICD 平台的应用配置页面
-
一键开启:勾选"开启观测"选项
-
参数配置:
-
应用语言:Java / Golang
-
采样率:0.1 - 1.0
-
-
自动部署:平台自动在 Deployment 上添加相应标签并重新部署
独立 K8s 环境接入
-
手动添加标签:``bashkubectl label deployment odyssey-apm-enable=truekubectl label deployment odyssey-apm-language=javakubectl label deployment odyssey-apm-sampling-rate=0.3
\
-
触发更新:``bashkubectl rollout restart deployment
\
-
验证接入:``bashkubectl describe deployment | grep -A 10 “Environment”
\
七、观测数据消费
7.1 阿里云 SLS 控制台
链路查询
-
入口:SLS 控制台 → sre-observability-monitor 项目 → odyssey-环境-traces 日志库
-
查询语法:```sql
- | SELECT \* FROM log WHERE service\_name = ‘user-service’ AND duration > 1000```
服务拓扑
-
自动生成:基于 Trace 数据自动构建服务依赖关系图
-
-
性能分析:展示服务间调用的延迟、错误率、吞吐量
7.2 自建 Grafana + Jaeger
https://apm.cds8.cn
sls自带监控大盘只是为了方便我们前期使用,最终还是会自己部署grafana去完成数据的在线观测,由于我们使用otel规范,所以可以很轻松的使用jaeger query插件完成trace的可视化展示,指标利用普罗米修斯去拉取指标数据即可。
Jaeger Query 部署
apiVersion: apps/v1
kind: Deployment
metadata:name: jaeger-query
spec:replicas: 1selector:matchLabels:app: jaeger-querytemplate:metadata:labels:app: jaeger-queryspec:containers:- name: jaeger-queryimage: jaegertracing/jaeger-query:latestenv:- name: SPAN_STORAGE_TYPEvalue: "elasticsearch"- name: ES_SERVER_URLSvalue: "http://elasticsearch:9200"ports:- containerPort: 16686
Grafana 数据源配置
-
添加 Jaeger 数据源:URL 指向 Jaeger Query 服务
-
添加 SLS 数据源:通过 SLS API 接入指标数据
-
创建综合大盘:整合链路、指标、日志的统一视图
八、监控告警策略
8.1 基础设施监控
指标 | 阈值 | 告警级别 |
---|---|---|
OTel Collector CPU 使用率 | > 80% | Warning |
OTel Collector 内存使用率 | > 85% | Warning |
Operator Pod 状态 | NotReady > 5min | Critical |
SLS 上报失败率 | > 5% | Warning |
8.2 应用观测告警
指标 | 阈值 | 告警级别 |
---|---|---|
服务响应时间 P99 | > 2s | Warning |
服务错误率 | > 1% | Warning |
服务错误率 | > 5% | Critical |
链路断点 | 检测到 | Warning |
九、性能优化与最佳实践
9.1 采样策略
分层采样
-
生产环境:默认 10% 采样率,关键服务 30%
-
测试环境:50% 采样率
-
开发环境:100% 采样率
动态采样
# 高 QPS 服务降低采样率
metadata:labels:odyssey-apm-sampling-rate: "0.1" # 10% 采样# 关键业务服务提高采样率
metadata:labels:odyssey-apm-sampling-rate: "0.5" # 50% 采样
9.2 资源配置建议
OpenTelemetry Collector
-
CPU:每 1000 spans/s 需要约 100m CPU
-
内存:每 1000 spans/s 需要约 128Mi 内存
-
网络:确保与 SLS 的网络连通性稳定
K8s Operator
-
CPU:100m(轻量级,主要处理 K8s API 调用)
-
内存:128Mi
-
权限:需要 Deployment 的 get、list、watch、update 权限
9.3 故障排查指南
常见问题
-
应用无链路数据
-
检查 Deployment 标签是否正确
-
验证 OTel Collector 是否正常运行
-
确认应用是否成功注入环境变量
-
-
链路数据不完整
-
检查采样率配置
-
验证服务间网络连通性
-
确认 SDK 版本兼容性
-
-
性能影响
-
调整采样率
-
优化 Collector 资源配置
-
检查 SLS 上报延迟
-
调试命令
# 查看 Operator 日志
kubectl logs -f deployment/odyssey-obser-operator -n odyssey-observability# 查看 Collector 状态
kubectl get pods -l app=odyssey-otel-collector -n odyssey-observability# 测试 OTLP 端点连通性
kubectl exec -it <app-pod> -- telnet localhost 55680# 查看应用环境变量
kubectl exec -it <app-pod> -- env | grep OTEL
本文章为本人在公司内部的技术分享,已隐去关键信息,欢迎大家讨论。