当前位置: 首页 > news >正文

OpenTelemetry 多租户分流怎么做:按服务名路由 traces 的实战方案

OpenTelemetry 多租户分流怎么做:按服务名路由 traces 的实战方案

一、问题背景:单租户 Collector 不够用了

我们平台早期只有一个业务方,OpenTelemetry Collector 收到 SDK 上报的 trace 后,一股脑往 Jaeger 后端写,看着挺干净。但从 Q2 开始,业务方从 1 个变成了 6 个:3 个 toB 业务线、2 个内部中台、1 个支付子链。每个业务方都要求"我的 trace 别跟别人混在一起"——倒不是技术洁癖,主要是:

  • 合规审计要求:支付子链的 trace 必须留存在我们自建的存储里,不能外发到第三方 SaaS。
  • 成本分摊:toB 业务线按 trace 量结算,要能按 service.name 切片统计每家用了多少。
  • 排查干扰:A 业务的告警如果命中 B 业务的 trace,定位效率会塌方。

一开始我天真地让每个业务方起一套独立的 OTel Agent + Collector + Jaeger,结果运维同学一周内就来找我骂街:6 套 collector、6 份配置、6 个 dashboard、6 个告警通道,更别说每多一套就多一个证书、多一个升级窗口。

这才回过味来:多租户的本质是"一份管道,多路出口",而不是"多份管道,每家一个"。今天我把最终跑通的方案拆给你看,按 service.name 路由 traces 到不同后端,配合独立的采样和落库策略。

一些关键的判断点

写方案之前,先明确两件事:

  1. 不要把"租户"和"服务"混为一谈:service.name 是 SDK 上报时打的标签,分流天然按它走;如果租户边界比服务更细(比如一个业务方有多个子服务,但数据要按业务方隔离),就需要再加一层 tenant_id 属性。
  2. 路由在 Collector 做,不在 SDK 做:让 SDK 关心业务,让 Collector 关心路由。SDK 只管打标签,Collector 的 connectors + routing processor 才是干这个的。

二、整体架构

[App SDK] --OTLP--> [Gateway Collector] --route--> [Tenant A Backend] (Jaeger) \--> [Tenant B Backend] (Tempo) \--> [Tenant C Backend] (Datadog) \--> default sink (ClickHouse)

三层 Collector 的设计:

  • Gateway (Agent 模式): 收 SDK 上报,做限流、auth、批处理,统一入口。
  • Router (Collector 模式): 核心路由层,按 service.name / tenant_id 决定把 trace 转发到哪。
  • Tenant Backend: 每个租户独立的后端存储,可以是 Jaeger / Tempo / ClickHouse / Datadog / S3+Athena 任意组合。

为什么不直接让 SDK 发到不同后端?因为 SDK 不该知道"后端在哪"。路由下沉到 Collector 后,未来加租户只需要改 Collector 配置,App 一行代码不动。

三、关键配置:Router Collector

下面是生产环境跑了大半年的 Router Collector 核心配置。注解直接写在 yaml 里:

# /etc/otelcol-contrib/config.yamlreceivers:otlp:protocols:grpc:endpoint:0.0.0.0:4317http:endpoint:0.0.0.0:4318processors:# 1. 批处理:聚合后批量转发,降低下游压力batch:timeout:5ssend_batch_size:8192# 2. 内存限制:保护 Collector 自身,防止 OOMmemory_limiter:check_interval:1slimit_percentage:80spike_limit_percentage:25# 3. 路由:核心!按 service.name 决定走哪条 export 链路routing/traces:default_pipelines:[traces/default]error_mode:ignoretable:# 租户 A:支付子链,必须落自建 Jaeger-context:resourcestatement:route() where attributes["service.name"]== "pay-gateway" \ or attributes["service.name"]== "pay-settlement"pipelines:[traces/tenant_a]# 租户 B:toB 业务线 A-context:resourcestatement:route() where attributes["service.name"]== "b2b-inventory" \ or attributes["service.name"]== "b2b-order"pipelines:[traces/tenant_b]# 租户 C:toB 业务线 B,要求用 Datadog-context:resourcestatement:route() where attributes["service.name"]== "b2b-report"pipelines:[traces/tenant_c]# 4. 不同租户独立采样(支付链路全采,报表链路 10% 采样)tail_sampling/tenant_a:decision_wait:10snum_traces:50000expected_new_traces_per_sec:5000policies:-name:keep-alltype:always_sampletail_sampling/tenant_b:decision_wait:10snum_traces:30000policies:-name:errors-onlytype:status_codestatus_code:{status_codes:[ERROR]}-name:slow-tracestype:latencylatency:{threshold_ms:500}-name:probabilistictype:probabilisticprobabilistic:{sampling_percentage:10}exporters:# 租户 A:自建 Jaegerotlp/tenant_a:endpoint:jaeger-tenant-a.internal:4317tls:insecure:falsecert_file:/etc/certs/jaeger-tenant-a.crtkey_file:/etc/certs/jaeger-tenant-a.keysending_queue:{enabled:true,num_consumers:10,queue_size:5000}retry_on_failure:{enabled:true,initial_interval:1s,max_interval:30s}# 租户 B:自建 Tempootlp/tenant_b:endpoint:tempo-tenant-b.internal:4317sending_queue:{enabled:true,num_consumers:10}# 租户 C:Datadog SaaSdatadog/tenant_c:api:key:${env:DD_API_KEY}site:datadoghq.com# 默认出口:长期冷存储 + 成本结算otlphttp/default:endpoint:https://clickhouse-traces.internal/v1/tracestls:{insecure:false}service:telemetry:logs:{level:info}pipelines:traces:receivers:[otlp]processors:[memory_limiter,batch,routing/traces]# routing 后会自动衍生出 traces/tenant_a, traces/tenant_b 等子 pipeline

几个容易踩坑的地方:

  • routingprocessor 配完之后,真正的子 pipeline 是运行时衍生出来的,配置里写不写都无所谓,Collector 会自动生成traces/<pipeline_name>
  • default_pipelines一定要配,否则没匹配上的 trace 会被直接丢弃——我们一开始漏了这条,报警响了才发现有 30% 的 trace 不见了。
  • error_mode: ignoresilent安全,前者会记日志,后者完全静默,排查时找不到线索。

四、踩过的坑

坑 1:service.name 写错,trace 全跑到 default 出口

SDK 默认把 service.name 设成unknown_service:<进程名>,结果一启动全跑到 default。强制要求所有 SDK 在启动时显式覆盖 service.name,我们用 lint 工具(OpenTelemetry SDK 提供的validate_service_name检查器)卡 CI,没填或填了unknown_开头的直接拦在流水线前。

坑 2:tail_sampling 改变了 trace 的完整性

在 Router Collector 上做 tail sampling 时,所有租户的 trace 都先汇总到这里再决定留还是丢。这意味着 tenant_a 的采样窗口(10s)会卡住 tenant_b 的转发速度。生产上我们做了两件事:

  1. tail_sampling放到每个租户的 Backend Collector 而不是 Router Collector,让路由零延迟。
  2. 在 Router 上只做 head sampling(按概率粗筛),把 90% 的噪声提前干掉,剩下的 trace 再交给租户后端精筛。

坑 3:批量 + 路由的顺序反了

routingprocessor 必须在batch之后。否则一条 batch 里 5 条 trace 分属 3 个租户,被一次性发到第一个匹配的下游,路由就废了。实际写配置时把 routing 放 batch 后是 OK 的,但反过来绝对不行。

坑 4:租户后端挂了,整个路由链路卡死

我们用sending_queue + retry_on_failure隔离每个租户后端的故障:tenant_a 的 Jaeger 短暂不可达时,queue 会兜住,retry 30 秒一次,其他租户完全不受影响。这块的sending_queue.num_consumers不能开太大,否则一个慢后端会吃满 Collector 的连接池。

五、成本与可观测性收益

上线半年后的几个关键数据:

  • 存储成本:分租户后,报表类业务(trace 量最大但价值最低)只采 10%,落 ClickHouse 冷存储,月度成本降了 62%。
  • 排障效率:支付链路全量采独立存储后,P0 故障平均定位时间从 18 分钟降到 6 分钟——主要是不再被无关 trace 干扰。
  • 接入新租户耗时:从原来的"开 6 套 collector + 6 套配置"变成"改一份 Router yaml 加 3 行",最快的一次 25 分钟完成新租户接入。

六、写在最后

把多租户分流做好,关键是认清三层角色:SDK 只管打标签,Router 只管分发,Backend 才管存储和查询。任何一层越界(比如让 SDK 知道后端地址、让 Backend 做路由),后续都会被自己埋的单点故障咬回来。

这套方案现在我们 6 个业务方共用一份 Router 配置,扩第 7 个租户基本就是改 yaml 的活。如果你也在搞多租户可观测性,希望这篇能给你一些可落地的参考。

EOF

http://www.gsyq.cn/news/1616138.html

相关文章:

  • 三步打造个人数字图书馆:novel-downloader小说下载器终极指南
  • Grok 4.5私测,马斯克AI战略是转型还是出清?
  • ESim电工制图图文介绍
  • Linux 系统编程 04:进程基础
  • 3分钟免费解锁全皮肤:R3nzSkin国服换肤终极指南
  • 贾扬清从英伟达离职,7 亿美元收购一年告终,AI Infra 赛道面临挑战
  • 深度解析SDINBDA6-128G-ZA1:闪迪128GB车规级eMMC 5.1存储芯片
  • 嵌入式交流群
  • 大宅门中式建筑,已按人物标准升高修改
  • 产业园区两轮车乱象难治理?观芯AI摄像头专项实测方案
  • 案例分析:100GigE高速相机的出现助力创新生物医学诊断
  • MC6470与TM4C1299NCZAD的硬件协同与6DOF数据融合实战
  • Vibe Coding 避坑指南:3 张提示词模板,把烂尾率从 80% 打下来
  • 2026滁州黄金回收白银回收铂金回收旧料回收怎么选?五家高实价铂金白银线下门店测评清单 + 联系方式
  • Resource 体系纵深实战:构建动态模板化代码片段的资源服务器
  • 为什么你的IDEA多模块项目永远跑不通?揭秘被官方文档隐藏的6个IDEA专属Maven生命周期陷阱
  • 美国公司弃 Claude 选 DeepSeek:成本降了,性能还提升了!
  • Momenta港股招股:营收三年翻三倍,65%市占率能否成物理AI时代定义者?
  • Go+DeepSeek-V3构建企业级代码审计系统
  • 高分Panel复现系列|三元突变比例图:从三组比例到三角坐标映射
  • 2026年食品行业PLM系统实施路径:从需求梳理到平台落地的关键步骤
  • 薄膜沉积CVD/PVD/ALD怎么选:一文看懂适用场景
  • 【Java】Java永久代:从诞生到终结的演进史
  • 该原标题存在营销诱导词,不符合要求,若按照关键词“重罪辩护”生成趋势洞察型标题,可改为:2026年重罪辩护行业趋势洞察:策略与挑战并存
  • 2026最新AI论文工具全解析,从新手到高手的进阶必备攻略
  • YimMenu终极指南:GTA5免费增强菜单与安全防护完全教程
  • Tool 定义进阶:异步处理、流式输出、进度反馈与错误码规范的生产级标准
  • 数据结构 五
  • ROG幻16Air Type-C外接显示器休眠唤醒雪花屏问题分析与解决
  • 济南天桥区上门电脑维修