3. 追踪数据采集架构:Agent 采集、SDK 埋点、无侵入式采集(eBPF)的对比与选型

在分布式追踪体系中,数据采集是决定覆盖度、性能开销与运维复杂度的核心环节。平台工程团队需要根据业务场景、技术栈与治理成熟度,在 Agent 采集、SDK 埋点与无侵入式采集(eBPF)三种主流方案中做出合理选型。本章从架构原理、接入成本、数据质量与适用边界四个维度进行系统性对比。

3.1 三种采集架构的核心原理

核心认知:三种方案并非互斥关系,生产环境中常采用“SDK + Agent”或“Agent + eBPF”的混合模式,以平衡覆盖度与性能。

3.1.1 Agent 采集(旁路代理模式)

Agent 以独立进程或 Sidecar 形式部署在宿主机或 Pod 内,通过监听网络流量、读取日志文件或对接运行时接口来捕获追踪数据。典型实现包括 Jaeger Agent、OpenTelemetry Collector 与 SkyWalking Agent。

  • 部署形态:DaemonSet(K8s)、Sidecar、主机级守护进程。
  • 数据来源:网络 socket 嗅探、日志 tail、Unix Domain Socket 接收。
  • 典型场景:已有 SDK 埋点但需要统一汇聚、协议转换或采样控制。

3.1.2 SDK 埋点(代码级侵入式)

SDK 以库的形式嵌入应用代码,通过 AOP(面向切面编程)、拦截器或手动插桩生成 Span。OpenTelemetry SDK、Jaeger Tracer、Zipkin Brave 均属此类。

  • 部署形态:依赖注入、Maven/Gradle 包、npm 包。
  • 数据来源:应用内部上下文(线程局部变量、异步钩子)。
  • 典型场景:需要精确控制 Span 边界、携带业务标签、跨线程/跨异步追踪。

3.1.3 无侵入式采集(eBPF 内核态)

eBPF 在内核态挂载钩子,拦截系统调用、网络包、函数入口/出口,无需修改应用代码即可捕获 RPC 调用、数据库操作与文件 I/O 的时序数据。Cilium、Pixie、Apache SkyWalking eBPF 探针是代表项目。

  • 部署形态:内核模块加载、特权容器、Operator。
  • 数据来源:kprobe、tracepoint、uprobe、XDP。
  • 典型场景:遗留系统、第三方闭源组件、全量网络拓扑发现。
选型警告:eBPF 无法捕获应用层自定义业务标签(如订单 ID、用户等级),且对内核版本有强依赖(推荐 5.10+)。SDK 埋点虽灵活,但多语言维护成本随微服务数量线性增长。

3.2 多维度对比矩阵

对比维度 Agent 采集 SDK 埋点 eBPF 无侵入
代码侵入性 低(仅需配置) 高(需修改代码) 无(零修改)
部署复杂度 中(需管理 Agent 生命周期) 低(依赖管理即可) 高(内核兼容性、特权要求)
数据丰富度 中(依赖协议解析) 高(可携带业务上下文) 中(仅系统级元数据)
性能开销 低~中(网络抓包有损耗) 低(仅 Span 创建时) 极低(内核态零拷贝)
多语言支持 语言无关 需每种语言独立 SDK 语言无关
异步/协程追踪 困难(上下文丢失) 原生支持(Context 传播) 困难(需 uprobe 辅助)
运维依赖 Agent 升级/配置管理 SDK 版本对齐 内核版本、安全策略

3.3 采集架构选型决策树

平台工程团队在选型时,建议按以下优先级依次评估:

  1. 是否允许修改应用代码? 否 → 优先 eBPF(系统级)或 Agent(网络级);是 → 进入下一步。
  2. 是否需要业务级标签(如用户 ID、订单号)? 是 → 必须使用 SDK 埋点;否 → 考虑 Agent 或 eBPF。
  3. 技术栈是否统一(如全 Java/Go)? 是 → SDK 埋点性价比最高;否 → Agent 或 eBPF 更通用。
  4. 性能敏感度是否极高(P99 < 5ms)? 是 → eBPF 内核态采集开销最低;否 → SDK 或 Agent 均可。
  5. 是否有遗留系统或第三方组件? 是 → 混合方案:SDK 覆盖核心服务 + eBPF 覆盖黑盒组件。
平台工程最佳实践:在 K8s 环境中,推荐“OpenTelemetry SDK(业务服务)+ eBPF(网络代理/Service Mesh)+ Agent(统一 Collector)”的三层采集架构。SDK 负责业务上下文,eBPF 负责无侵入覆盖,Agent 负责协议转换与采样降级。

3.4 采集架构对比总览图

三种追踪采集架构对比总览 三种追踪采集架构对比总览 Agent 采集(旁路代理) • 独立进程 / Sidecar 部署 • 监听网络 / 日志 / UDS • 语言无关,统一汇聚 • 典型:OTel Collector • 适用:协议转换 / 采样 • 开销:低~中 SDK 埋点(代码侵入) • 库注入 / AOP 拦截 • 精确 Span 边界控制 • 携带业务上下文标签 • 典型:OTel SDK • 适用:核心业务服务 • 开销:低 eBPF 无侵入(内核态) • 内核钩子 / 零修改代码 • 系统调用 / 网络包捕获 • 语言无关,全量覆盖 • 典型:Pixie / Cilium • 适用:遗留 / 黑盒组件 • 开销:极低 平台工程推荐:三层混合采集架构 SDK(业务上下文) + eBPF(无侵入覆盖) + Agent(统一汇聚/采样) 覆盖核心服务、遗留系统、第三方组件,平衡数据质量与运维成本

3.5 混合采集架构部署拓扑

下图展示了一个典型的生产级混合采集部署拓扑,适用于 K8s 环境下的微服务集群:

混合采集架构部署拓扑 混合采集架构部署拓扑(K8s 环境) 核心业务 Pod • Java/Go 服务 • OTel SDK 埋点 • 携带业务标签 • 异步 Context 传播 • 低开销 Span 生成 遗留系统 / 第三方 Pod • PHP/Python 旧服务 • 无法修改代码 • 无 SDK 支持 • 黑盒组件 • 需无侵入覆盖 eBPF 内核采集层 • kprobe / tracepoint • 网络包 / 系统调用 • 零代码修改 • 全量网络拓扑 • 内核 5.10+ 依赖 Span 数据 系统调用 / 网络事件 Agent Collector(统一汇聚层) 协议转换 / 采样降级 / 标签增强 / 负载均衡 统一导出 追踪后端(Jaeger / Tempo / ClickHouse)

3.6 选型决策清单

场景特征 推荐方案 理由
全 Java 技术栈,团队可控 SDK 埋点 最低开销、最丰富上下文、最易调试
多语言异构,无统一 SDK Agent + eBPF 语言无关,统一采集面
遗留系统无法修改代码 eBPF 无侵入 零修改,快速覆盖
需要全量网络拓扑 eBPF + Agent eBPF 捕获网络流,Agent 做协议解析
核心交易链路需精细追踪 SDK 埋点 + Agent SDK 保证业务标签,Agent 保证汇聚质量
性能敏感(P99 < 3ms) eBPF 为主 内核态零拷贝,无用户态上下文切换
平台工程关键指标:在混合采集架构中,需持续监控以下三个 SLO:
• 采集覆盖率 ≥ 95%(所有服务至少被一种方案覆盖)
• Span 丢失率 ≤ 1%(Agent 或 eBPF 采样导致的丢失)
• 额外延迟注入 ≤ 0.5ms(SDK 或 eBPF 对请求延迟的影响)

3.7 常见选型误区与避坑

  • 误区一:eBPF 可以完全替代 SDK。 事实:eBPF 无法捕获应用层业务上下文,无法替代 SDK 在异步/协程场景下的 Context 传播。
  • 误区二:Agent 采集是“零侵入”。 事实:Agent 虽不修改代码,但需管理 Agent 生命周期、配置与版本,运维成本不可忽视。
  • 误区三:SDK 埋点性能开销可忽略。 事实:在高并发(>10k QPS)场景下,SDK 的 Span 创建与序列化仍会产生 1-3% 的 CPU 开销,需配合采样策略。
  • 误区四:全量采集优于采样。 事实:全量采集在 1000+ 服务规模下会导致存储成本爆炸,必须设计动态采样策略(如 Head-Based + Tail-Based 混合采样)。
生产级建议:在引入 eBPF 前,务必验证目标集群的内核版本(uname -r)是否 ≥ 5.10,并确认安全策略允许加载 eBPF 程序。对于金融、合规敏感场景,eBPF 的内核态数据捕获可能需要额外的安全审计。