Skip to content

聚合表跨 Collector 同步设计文档

1. 背景与目标

为避免同一需求在多个分支重复开发,需要在当前 collector 中增加一套一次性、最简化的聚合数据同步能力:

  • 聚合数据范围仅限以下 6 张表对应的数据:
    • span_agg
    • span_summary_agg
    • span_error_agg
    • span_event_agg
    • span_event_summary_agg
    • span_event_database_agg
  • 发送端:本地照常落库,同时将聚合数据通过 OpenFeign 异步发往另一个 collector。
  • 接收端:仅接收并保存上述聚合数据,逻辑独立,不与原主链路混用。

说明:该需求明确不要求幂等、强一致、补偿与回放机制。


2. 设计原则(按本需求约束)

  • 最小改动:尽量复用现有聚合结果对象与现有 SpanStorage 入库方法。
  • 双开关互斥:发送开关与接收开关不能同时开启,避免回流。
  • 发送不阻塞主流程:发送失败、超时、对端不可达均不影响本地写库。
  • 接收独立处理:接收接口只负责聚合数据入库,不触发原始 span 计算链路。

3. 配置设计

application*.yml 中新增以下配置(示例命名):

yaml
aggSync:
  sendEnabled: false
  receiveEnabled: false
  targetBaseUrl: http://other-collector:port
  connectTimeoutMs: 1000
  readTimeoutMs: 1500

3.1 互斥规则

  • sendEnabled=true 时,receiveEnabled 必须为 false
  • receiveEnabled=true 时,sendEnabled 必须为 false
  • 两者都 false 允许(功能关闭)
  • 若两者都 true,服务启动直接失败(抛配置异常)

建议在配置初始化阶段做校验(如 @PostConstruct / @ConfigurationProperties 校验)。


4. 总体架构

text
                ┌──────────────────────────────┐
                │   当前 Collector(发送模式)  │
                │ sendEnabled=true              │
                └──────────────┬───────────────┘

         本地聚合入库成功后      │ 异步(不阻塞)

                    OpenFeign 调用 HTTP

                ┌──────────────────────────────┐
                │  目标 Collector(接收模式)   │
                │ receiveEnabled=true           │
                └──────────────┬───────────────┘


                       仅保存 6 张聚合表

5. 发送端设计(sendEnabled=true)

5.1 触发时机

在现有聚合计算完成并写本地库后触发发送。
建议接入点:

  • BatchSpanInsertProcessor
  • BatchSpanChunkInsertProcessor

触发内容仅包含本批次聚合结果(6类 list)。

5.2 行为定义

  • 发送端始终先执行本地入库(现有逻辑不变)
  • 本地入库后,异步调用 Feign 发送聚合数据到目标 collector
  • 不等待发送结果,不向主链路抛错
  • 发送失败仅记录日志(warn/error),不重试、不补偿

5.3 异步执行

  • 使用独立线程池(如 TaskExecutor)或 CompletableFuture.runAsync
  • 禁止在批处理主线程中同步等待网络返回

6. 接收端设计(receiveEnabled=true)

6.1 新增内部接口

建议新增内部接口(示例):

  • POST /internal/agg-sync/batch

接口仅用于接收发送端推送的聚合数据。

6.2 接收处理流程

  1. 校验 receiveEnabled=true,否则拒绝请求
  2. 解析请求体(6类聚合列表)
  3. 调用独立接收服务 AggSyncReceiveService
  4. 直接调用现有 SpanStorage 的批量插入方法保存到 6 张聚合表
  5. 返回成功响应

6.3 独立性要求

  • 不进入 SpanBo/SpanEventBo 原始计算链路
  • 不触发本地聚合再计算
  • 不触发向外转发(由开关互斥保障)

7. 接口与数据结构

7.1 Feign Client(发送端)

新增 OpenFeign 客户端(示例):

  • AggSyncFeignClient#syncBatch(AggSyncBatchRequest request)

7.2 请求 DTO(建议)

AggSyncBatchRequest

  • List<SpanAggValue> spanAggList
  • List<SpanSummaryAggValue> spanSummaryAggList
  • List<SpanErrorAggValue> spanErrorAggList
  • List<SpanEventAggValue> spanEventAggList
  • List<SpanEventSummaryAggValue> spanEventSummaryAggList
  • List<SpanEventDatabaseAggValue> spanEventDatabaseAggList

为最简实现,可直接复用现有 VO;若考虑边界清晰,可定义独立 DTO 再做一次映射。


8. 模块划分建议

建议新增包(命名可按现有规范调整):

  • collector.sync.agg.config
    • 开关与互斥校验配置
  • collector.sync.agg.client
    • OpenFeign Client
  • collector.sync.agg.dispatch
    • 发送分发器(异步)
  • collector.sync.agg.controller
    • 接收接口 Controller
  • collector.sync.agg.service
    • 接收端独立入库 Service
  • collector.sync.agg.dto
    • 请求/响应对象

9. 主流程改造点(最小侵入)

在聚合批处理写库逻辑后增加可选发送:

  1. 判断 sendEnabled
  2. 组装请求对象(6类聚合 list)
  3. 提交异步任务调用 Feign
  4. 捕获并吞掉异常,仅日志记录

原有本地写库流程、聚合算法、表结构均不改。


10. 日志与可观测性(最简)

发送端建议日志:

  • 本批次发送触发(各 list size)
  • 发送成功(debug/info)
  • 发送失败(warn/error,带异常与目标地址)

接收端建议日志:

  • 接收请求(各 list size)
  • 入库成功
  • 入库失败

11. 风险说明(按当前约束接受)

由于明确采用最简方案,以下风险视为可接受:

  • 发送失败会导致两端数据不一致
  • 网络抖动时可能丢批次
  • 无幂等可能导致重复入库(若调用方重复发送)
  • 无补偿与回放机制

12. 验收标准

12.1 发送模式

  • sendEnabled=true, receiveEnabled=false
  • 本地聚合表照常写入
  • 对端可达时,收到并写入同批聚合数据
  • 对端不可达时,本地不受影响,主链路无阻塞

12.2 接收模式

  • sendEnabled=false, receiveEnabled=true
  • 能通过内部接口接收聚合数据并写入 6 张聚合表
  • 不触发本地再转发

12.3 配置互斥

  • sendEnabled=truereceiveEnabled=true 时,应用启动失败并给出明确报错。

13. 后续下线建议

需求结束后建议:

  1. 先在所有环境关闭 sendEnabled/receiveEnabled
  2. 观察稳定后移除同步代码与配置
  3. 保留本文档作为变更记录