3.9 KiB
3.9 KiB
| name | overview | todos | isProject | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 修复海康请求ID重复 | 确认根因是多实例部署下 `SnowflakeIdGenerator` 固定 `workerId=1, datacenterId=1`,同毫秒生成相同雪花 ID,导致并发海康请求的 `X-LR-REQUEST-ID` 重复。计划将海康 HTTP 请求 ID 改为 UUID 生成,避免跨实例碰撞。 |
|
false |
修复海康 X-LR-REQUEST-ID 多实例重复
问题确认
两条并发海康 task/submit 请求日志:
- 不同 traceId:
5190815295754e028131f7bc18502911/5bf388d7211f4001bf7248d417240543 - 不同任务号:
MC2072288711575474302/MC2072288711575474213 - 不同线程:
robot-async-12/robot-async-16 - 相同
X-LR-REQUEST-ID:ASRS2072313718577958912
当前生成逻辑在 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,与项目内同类场景保持一致:
WebClientUtil对X-LR-REQUEST-ID已用UUID.randomUUID().toString().replace("-", "")- 旧版
HikServiceClient用RobotCodeGenerator,跨实例仍有同毫秒碰撞风险
变更点(1 个文件,约 2 行)
修改 MachineIntegrationAutoConfiguration.java:
// 替换
String requestId = "ASRS" + SnowflakeIdGenerator.generate();
// 为
String requestId = "ASRS" + UUID.randomUUID().toString().replace("-", "");
- 移除
SnowflakeIdGeneratorimport,增加java.util.UUIDimport - 日志与
.header(requestIdHeader, requestId)逻辑不变 - 重试分支(
doCall递归)每次仍会生成新 UUID,行为合理
为何不用给 Snowflake 配 workerId
X-LR-REQUEST-ID只是外部请求幂等/追踪头,不需要时间有序- UUID 零配置、跨实例天然唯一,改动最小
- 配置 workerId 需要 K8s/部署侧配合,且
CreateCodeUtil.machineTaskChainCode()也共用同一SnowflakeIdGenerator,若要彻底修复 MC 号碰撞需另做专项
验证
- 编译
baoshi-robot-integration模块 - 本地或测试环境并发触发 2+ 个海康
createTask,确认日志中X-LR-REQUEST-ID均不同 - 多 Pod 部署下复测(重点场景)
后续风险(本次不改动)
MC 任务链号同样使用 SnowflakeIdGenerator.generate(),多实例极端并发下理论上也可能重复。若线上曾出现 MC 号冲突,建议单独立项:按实例配置 workerId 或改为 Redis 递增号段。