登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

分布式系统迁移到统一遥测协议时如何设计双写和回退窗口

来源:17golang原创

时间:2026-09-20 07:11:40 147浏览 收藏

分布式系统迁移到统一遥测协议时,最稳妥的做法不是先删掉旧 exporter,而是在 Collector 或等价的遥测转发层保留一份规范化数据,同时写入旧后端和新 OTLP 后端。双写期间只允许新链路承担灰度流量,等接收量、导出成功率、延迟、丢失率和关键查询结果都达到退出条件,再关闭旧链路;任何一项持续恶化,都能把路由切回旧后端。

官方文档:https://opentelemetry.io/docs/compatibility/migration/

要点速览
  • 把协议迁移放在采集与转发边界,避免每个业务服务重复埋点。
  • 双写不是永久复制,必须有开始条件、对照指标、扩大灰度条件和截止时间。
  • 回退优先切 exporter 或路由;不要在故障时临时改埋点、改语义字段。

统一遥测协议迁移,先划清三条边界

OpenTelemetry 官方迁移页把 OpenTracing、OpenCensus 的迁移路径单独列出,也说明 Jaeger 后端可以通过 OTLP 接收 trace。对迁移负责人来说,第一步不是改版本号,而是列出三类边界:应用产生什么信号,Collector 负责怎样接收和规范化,后端分别接受什么协议与语义。

如果旧系统有多种入口,可以让旧 receiver 与 OTLP receiver 进入同一套处理规则;如果应用已经能直接发 OTLP,就不要再在应用层复制一份“旧格式埋点”。这样双写只存在于转发层,回退时也只切换 exporter 或路由,业务代码保持不变。

OpenTelemetry 迁移中旧采集入口和 OTLP 入口经过规范化处理后双写到新旧后端的架构说明图
图1:双写架构说明图,展示统一处理链与两个 exporter 的边界。

双写应该放在应用层还是 Collector 层

通常优先放在 Collector 层。Collector 的 pipeline 本来就按 receiver、processor、exporter 组织数据,并支持让一个处理结果扇出到多个 exporter。配置可以按下面的思路写,名称只是示意,真实 exporter 要以目标后端的官方支持为准。

service:
  pipelines:
    traces:
      receivers: [legacy_receiver, otlp]
      processors: [memory_limiter, normalize_attributes]
      exporters: [legacy_backend, otlp/new_backend] # 同一份数据进入旧、新后端

    metrics:
      receivers: [legacy_metrics, otlp]
      processors: [memory_limiter, normalize_attributes]
      exporters: [legacy_metrics_backend, otlp/new_metrics] # 指标也要单独对照

这里的关键不是复制 YAML,而是让两条出口共享同一份处理结果。把属性改名、资源归属和采样策略集中在 processor,能减少新旧后端因为字段不一致产生的假差异。若两套 backend 的语义无法完全映射,就先记录差异清单,不能用“查询数量接近”掩盖字段丢失。

还要注意 Collector 的背压:官方架构文档指出,共享 receiver 的多个 pipeline 通过同步 fan-out 传递数据,一个阻塞的 processor 可能拖住其他 pipeline。因此双写前要单独观察队列、重试、超时和 exporter 错误,必要时把慢出口拆到独立的 gateway 或队列边界。

回退窗口要看哪些信号

回退窗口不是“新后端能收到数据”这么简单,至少建立一张新旧对照表。每个信号都要定义观察范围和动作,不要等出现大面积告警后才决定是否回退。

信号对照方式不通过时的动作
接收量按服务、信号类型比较进入量暂停扩大灰度,检查 receiver 与路由
导出成功率分别看两个 exporter 的成功、重试和失败保留旧出口,先处理新出口错误
延迟与丢失看端到端时间、队列积压和重试耗尽切回旧路由,保留现场数据
查询一致性抽取同一服务和时间窗核对 trace、metric、log检查资源属性、采样和语义映射

扩大灰度应以“连续观察窗口内没有新增不可解释差异”为条件,而不是只看一次成功请求。回退动作则要足够短:冻结新服务名单、把路由指回旧 exporter、保留新链路只读观测,最后再分析差异。不要在回退过程中同时升级 Collector、改采样率和重命名属性,否则无法判断真正原因。

统一遥测协议迁移窗口中接收量、导出成功率、延迟、丢失率与查询一致性共同决定灰度或回退的说明图
图2:回退窗口信号说明图,展示迁移期间的对照指标和决策边界。

什么时候可以关闭旧链路

建议按服务或业务域分批推进:先选流量稳定、查询责任清晰的服务,完成双写和对照;再把同一套检查清单复制到下一批。旧 exporter 的关闭条件至少包括:新后端覆盖目标信号、关键查询能由新数据独立完成、回退配置已保存、值班人员知道切换入口,并且过了约定的观察窗口。

窗口结束后记录迁移批次、服务范围、异常与回退次数,再关闭旧出口。若仍有服务依赖旧协议,就保留它们的明确清单,不要为了“全量完成”强行删除兼容层。

延伸问答

双写会不会让遥测数据翻倍?

两个 exporter 各收到一份数据是预期行为,但新旧后端的存储费用、采样和查询结果要分别核算。不要把跨后端的两份数据当作一次业务事件重复计费。

能不能直接让应用同时调用两个 exporter?

小规模验证可以,但长期迁移通常会把协议、重试和回退逻辑扩散到业务代码。集中到 Collector 更容易按服务灰度,也能统一记录失败和积压。

什么时候应该放弃继续双写?

当新链路在多轮观察中仍出现无法解释的丢失、字段语义冲突或持续背压时,应先回退并缩小问题边界,而不是延长窗口掩盖风险。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>