本文用于排查和补偿 SAAS 向 DGJ 同步维修厂订单、订单更新和出库单时的消息丢失、顺序错乱、锁冲突与重试耗尽问题。公开文档只保留流程和判断规则,不记录内网地址、令牌、客户订单号或完整业务报文。
1. 核心入口
- 消费者:
app/Amqp/Consumer/Dgj/DgjConsumer.php - 延迟队列声明:
app/Listener/MainWorkerStartListener.php - 订单同步:
app/Service/Order/Sync/GarageRepairOrderSyncService.php - 出库同步:
app/Service/Order/Sync/GarageRepairOutboundSyncService.php - 主要事件:
garage_repair_order_created、garage_repair_order_updated、garage_repair_outbound_created
2. 排查顺序
- 使用订单 ID、订单号、出库单号和
sid查询消息接收、事务开始、事务完成、锁冲突和重试耗尽日志。 - 查询 SAAS 分表订单、订单明细和
t_order_out_flow,确认业务事实是否已经落库。 - 订单不存在时先补订单创建;订单存在但出库流水不存在时再补出库创建。
- 如果存在待补偿缓存,先确认订单创建是否会自动排空缓存,避免重复手工补发。
- 补偿后同时验证日志、订单状态、明细出库数量和出库流水。
3. 重试规则
- 生产者的延迟后缀必须与消费者启动时声明的 TTL 队列一致。
- 死信路由必须回到正常消费 routing key。
- 锁异常不能无边界
REQUEUE,否则会形成同一消息的热循环消费。 eventId会在延迟重试时变化,统计风暴时还要按业务键去重。- 对比健康时段和异常起点,结合连接中断、消费者重启、锁失败和
retry_times判断根因。
4. 补偿安全条件
- 默认先只读检查,不直接重发。
t_order_out_flow.out_bill_no已存在时禁止重复补发出库事件。- 订单创建和出库创建必须按依赖顺序执行。
- 补偿接口地址、会话令牌和完整 payload 从受控环境临时取得,不写入网站、技能、提交或聊天记录。
5. 验收清单
- 订单同步事务完成且没有持续锁冲突。
- 订单主表状态和出库单号正确。
- 明细出库数量与来源单一致。
t_order_out_flow只有一条目标出库事实。- 延迟队列没有继续产生同一业务键的无界重试。
- 失败告警和待补偿缓存已恢复或有明确后续负责人。
6. 改动风险
- 修改 QoS、锁 TTL、延迟 TTL 或重试次数时必须一起检查生产者、队列声明和消费者处理。
- 修改订单/出库幂等条件时要回归乱序、重复、订单未就绪、明细未就绪和消费者重启场景。
- 任何补偿都需要保存脱敏后的执行时间、事件类型、判断依据和验收结果。