cursor/plans/修复海康请求id重复_693ddb99.plan.md

3.9 KiB
Raw Blame History

name overview todos isProject
修复海康请求ID重复 确认根因是多实例部署下 `SnowflakeIdGenerator` 固定 `workerId=1, datacenterId=1`,同毫秒生成相同雪花 ID导致并发海康请求的 `X-LR-REQUEST-ID` 重复。计划将海康 HTTP 请求 ID 改为 UUID 生成,避免跨实例碰撞。
id content status
fix-request-id MachineIntegrationAutoConfigurationX-LR-REQUEST-ID 改为 ASRS + UUID去掉 SnowflakeIdGenerator pending
id content status
compile-verify 编译 baoshi-robot-integration 并并发验证请求 ID 唯一性 pending
false

修复海康 X-LR-REQUEST-ID 多实例重复

问题确认

两条并发海康 task/submit 请求日志:

  • 不同 traceId5190815295754e028131f7bc18502911 / 5bf388d7211f4001bf7248d417240543
  • 不同任务号:MC2072288711575474302 / MC2072288711575474213
  • 不同线程:robot-async-12 / robot-async-16
  • 相同 X-LR-REQUEST-IDASRS2072313718577958912

当前生成逻辑在 MachineIntegrationAutoConfiguration.java

String requestId = "ASRS" + SnowflakeIdGenerator.generate();

SnowflakeIdGenerator 写死 IdUtil.getSnowflake(1, 1)。单 JVM 内 nextId() 是 synchronized 的,不会重复;多实例同 workerId/datacenterId 时,同毫秒会产出相同 ID

sequenceDiagram
    participant PodA as PodA_robot_async_12
    participant PodB as PodB_robot_async_16
    participant HK as Hikvision_RCS

    PodA->>PodA: Snowflake(1,1) -> 2072313718577958912
    PodB->>PodB: Snowflake(1,1) -> 2072313718577958912
    PodA->>HK: X-LR-REQUEST-ID=ASRS2072313718577958912
    PodB->>HK: X-LR-REQUEST-ID=ASRS2072313718577958912

修复方案(推荐)

海康 HTTP 请求 ID 改用 UUID,与项目内同类场景保持一致:

  • WebClientUtilX-LR-REQUEST-ID 已用 UUID.randomUUID().toString().replace("-", "")
  • 旧版 HikServiceClientRobotCodeGenerator,跨实例仍有同毫秒碰撞风险

变更点1 个文件,约 2 行)

修改 MachineIntegrationAutoConfiguration.java

// 替换
String requestId = "ASRS" + SnowflakeIdGenerator.generate();
// 为
String requestId = "ASRS" + UUID.randomUUID().toString().replace("-", "");
  • 移除 SnowflakeIdGenerator import增加 java.util.UUID import
  • 日志与 .header(requestIdHeader, requestId) 逻辑不变
  • 重试分支(doCall 递归)每次仍会生成新 UUID行为合理

为何不用给 Snowflake 配 workerId

  • X-LR-REQUEST-ID 只是外部请求幂等/追踪头,不需要时间有序
  • UUID 零配置、跨实例天然唯一,改动最小
  • 配置 workerId 需要 K8s/部署侧配合,且 CreateCodeUtil.machineTaskChainCode() 也共用同一 SnowflakeIdGenerator,若要彻底修复 MC 号碰撞需另做专项

验证

  1. 编译 baoshi-robot-integration 模块
  2. 本地或测试环境并发触发 2+ 个海康 createTask,确认日志中 X-LR-REQUEST-ID 均不同
  3. 多 Pod 部署下复测(重点场景)

后续风险(本次不改动)

MC 任务链号同样使用 SnowflakeIdGenerator.generate(),多实例极端并发下理论上也可能重复。若线上曾出现 MC 号冲突,建议单独立项:按实例配置 workerId 或改为 Redis 递增号段。