数据一致性策略
本文引用的文件
- yudao-module-system-biz/SmsSendConsumer.java
- yudao-module-rule-biz/RuleBusinessLimitConsumer.java
- yudao-spring-boot-starter-bus/pom.xml
- yudao-spring-boot-starter-mq/RedisPendingMessageResendJob.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
- yudao-module-bpm-biz/BpmInstanceStatusMessageServiceImpl.java
- yudao-module-device-biz/DeviceRuntimeCountJob.java
- yudao-module-rule-api/RuleCanEditEvent.java
- yudao-spring-boot-starter-websocket/KafkaWebSocketMessageConsumer.java
- yudao-module-rule-api/本次需求2.md
目录
引言
本策略文档面向 yudao-cloud 在分布式环境下的数据一致性挑战,系统性阐述最终一致性的实现机制与工程化落地,覆盖消息队列异步处理、事件驱动架构、补偿与重试、分布式事务处理方案(Saga/TCC)、双写一致性与读写分离下的数据一致性保障,并给出一致性级别选择、性能权衡与故障恢复的技术决策。
项目结构
yudao-cloud 采用多模块微服务架构,围绕“基础设施层”“业务模块层”“消息中间件与总线”“一致性保障组件”四个维度组织。其中:
- 基础设施层:提供 MQ 统一抽象、Redis 分布式锁、WebSocket 消息通道、定时任务等通用能力。
- 业务模块层:如系统、规则、设备、流程等模块,负责具体业务逻辑与对外接口。
- 消息中间件与总线:支持 Kafka/RocketMQ/RabbitMQ/Redis Streams 等多种传输介质;Spring Cloud Bus 提供广播能力。
- 一致性保障组件:基于 Redis 分布式锁、本地队列兜底、Pending 消息重投、本地消息表等手段实现最终一致性。
图示来源
- yudao-spring-boot-starter-bus/pom.xml
- yudao-spring-boot-starter-mq/RedisPendingMessageResendJob.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
章节来源
- yudao-spring-boot-starter-bus/pom.xml
- yudao-spring-boot-starter-mq/RedisPendingMessageResendJob.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
核心组件
- 消息队列与总线
- 支持 Kafka/RocketMQ/RabbitMQ/Redis Streams 多实现,统一抽象便于替换与扩展。
- Spring Cloud Bus 提供广播能力,用于跨节点事件通知与回调。
- 分布式锁
- 基于 Redis 的 setIfAbsent + 过期时间 + 值校验的分布式锁工具,保障幂等与串行化。
- 本地队列与重试
- Kafka 消费侧在获取分布式锁失败时,将消息放入本地阻 塞队列,后台线程兜底重试,避免丢失。
- Redis Stream Pending 消息定期扫描与重投,提升崩溃后消息处理的可靠性。
- 事件驱动与补偿
- 业务模块通过 Kafka 发送事件,消费侧幂等处理;必要时采用本地消息表记录发送与处理状态,支持人工重试与追踪。
- 双写与影子库
- 设备模块通过影子库与 Nacos 动态切换,实现平滑的数据源迁移与双写验证,降低一致性风险。
章节来源
- yudao-module-system-biz/SmsSendConsumer.java
- yudao-module-rule-biz/RuleBusinessLimitConsumer.java
- yudao-spring-boot-starter-mq/RedisPendingMessageResendJob.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
- yudao-module-device-biz/DeviceRuntimeCountJob.java
架构总览
yudao-cloud 的一致性策略以“事件驱动 + 最终一致 + 幂等 + 补偿”为核心,结合分布式锁与本地队列兜底,确保跨服务、跨数据源场景下的数据一致性。
图示来源
- yudao-module-rule-biz/RuleBusinessLimitConsumer.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
详细组件分析
组件A:规则模块的业务限流与幂等处理
规则模块通过 Kafka 消费事件,结合 Redis 分布式锁与本地队列,实现高并发下的幂等与可靠处理。
图示来源
- yudao-module-rule-biz/RuleBusinessLimitConsumer.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
章节来源
- yudao-module-rule-biz/RuleBusinessLimitConsumer.java
- yudao-spring-boot-starter-redis/RedisDistributionLockUtils.java
组件B:系统模块的短信发送事件处理
系统模块通过 Spring Event + @Async 实现异步短信发送,避免阻塞主流程,体现事件驱动与解耦。
图示来源
章节来源
组件C:规则编辑权限的事件驱动校验
规则模块通过 Kafka 与 Spring Cloud Bus 实现“规则 → 业务”的请求-回调模式,消费侧需幂等处理并返回结果。
图示来源
章节来源
组件D:WebSocket 消息的 Kafka 广播
WebSocket 消息通过 Kafka 广播,每个消费者组实例使用唯一 groupId 实现广播消费,确保消息到达所有节点。
图示来源
章节来源
组件E:Redis Stream Pending 消息重投
Redis Stream 在消费者崩溃或处理超时后,通过定时任务扫描 Pending 队列并重投,保障消息不丢失。
图示来源
章节来源
组件F:流程实例状态消息的重发与补偿
流程模块提供消息重发能力,当消息发送失败时,支持按消息键重发并记录重试次数,便于人工介入与追踪。
章节来源
组件G:设备模块的影子库与数据源切换
设备模块通过“影子库 + Nacos 动态切换 + 导出/导入/重置”的方式,实现平滑的数据源迁移与双写验证,降低一致性风险。
图示来源
章节来源
依赖关系分析
- 模块间耦合
- 业务模块通过 MQ 与总线与外部交互,降低直接 RPC 调用带来的强耦合。
- 规则模块与业务模块通过事件驱动解耦,消费侧需幂等处理。
- 外部依赖
- Kafka/RocketMQ/RabbitMQ/Redis Streams 提供高吞吐、低延迟的消息传递。
- Spring Cloud Bus 提供广播与配置刷新能力。
- 循环依赖
- 通过事件与消息解耦,避免模块间的直接循环调用。
图示来源
章节来源
性能考量
- 异步与解耦
- 通过事件驱动与消息队列异步处理,显著降低请求链路延迟,提升吞吐。
- 幂等与重试
- 消费侧幂等设计与本地队列兜底,减少重复计算与资源浪费。
- 分布式锁粒度
- 以“业务类型+业务ID”为维度的细粒度锁,避免全局阻塞,提高并发。
- Redis Stream Pending 重投
- 通过定时扫描 Pending,平衡消息可靠性与系统负载。
- 双写与影子库
- 影子库双写验证与 Nacos 动态切换,降低迁移期间的一致性风险与停机时间。
故障排查指南
- 消息堆积与积压
- 检查消费者线程池与分区数量,评估是否需要扩容或优化消费逻辑。
- 关注本地队列容量与重试策略,避免队列溢出导致丢弃。
- 消费失败与重试
- 查看 Redis 分布式锁是否正确释放,避免死锁导致的持续重试。
- 对 Redis Stream 场景,确认 Pending 消息重投任务是否正常运行。
- 业务补偿
- 对于流程模块的消息重发失败,根据消息键定位并重发,记录重试次数。
- 本地消息表
- 规则模块需求中提到本地消息表方案,建议在 MQ 多次失败后,采用私信队列记录并提供人工重试界面。
章节来源
结论
yudao-cloud 在分布式环境下以“事件驱动 + 最终一致 + 幂等 + 补偿”为核心策略,结合 Redis 分布式锁、本地队列兜底、Pending 消息重投与影子库双写验证,有效平衡了性能与一致性。对于强一致需求,建议优先采用本地消息表与 补偿机制,辅以 Saga/TCC 的长事务编排,确保跨服务的数据一致性与可恢复性。
附录
- 一致性级别选择
- 金融级强一致:采用本地消息表 + 补偿(Saga/TCC)。
- 业务级强一致:采用 Redis 分布式锁 + 幂等 + 本地队列兜底。
- 最终一致:采用 Kafka/RabbitMQ + 幂等 + Pending 重投。
- 性能权衡
- 异步解耦提升吞吐,但需关注幂等与补偿成本。
- 分布式锁粒度与超时设置影响并发与稳定性。
- 故障恢复
- 本地消息表与私信队列记录失败消息,提供人工重试与可视化追踪。
- Redis Stream Pending 重投与 Kafka/RabbitMQ 的重试策略协同,提升可靠性。