新闻详情

新闻详情

首页 / 资讯中心 / 详情

微服务事件驱动数据管理深度解析:从分布式事务难题到最终一致性实战方案(advanced-java)

发布时间:2026/9/18 13:32:20来源:尧图网络
微服务事件驱动数据管理深度解析:从分布式事务难题到最终一致性实战方案(advanced-java)
微服务事件驱动数据管理深度解析从分布式事务难题到最终一致性实战方案advanced-java【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/gh_mirrors/ad/advanced-java导读微服务架构下每个服务拥有自己的私有数据库数据访问只能通过服务 API 进行这带来了跨服务事务一致性维护与多服务数据查询两大核心挑战。本文基于 advanced-java 仓库中「微服务的事件驱动数据管理」章节系统剖析事件驱动架构Event-Driven Architecture如何借助消息代理实现跨服务业务交易与最终一致性视图并深入对比本地事务 EVENT 表、交易日志挖掘、事件源Event Sourcing三种实现原子性的方案及其优缺点帮助读者在面试与实战中建立完整的微服务数据管理认知体系。一、微服务与分布式数据管理问题1.1 单体应用的 ACID 优势单体式应用一般都会有一个关系型数据库由此带来的好处是应用可以使用 ACID 事务从而获得四个重要的操作特性原子性Atomicity——任何改变都是原子性的一致性Consistency——数据库状态一直是一致性的隔离性Isolation——即使事务并发执行看起来也是串行的持久性Durability——一旦事务提交了就不可回滚。凭借以上特性应用可以简化为一个固定套路开始一个事务 → 改变插入、删除、更新很多行 → 提交这些事务。关系型数据库带来的另一大优势在于 SQL 支持。SQL 是一种功能强大、可声明、面向表转化的查询语言用户可以通过查询轻松将多个表的数据组合起来RDBMS 查询调度器会决定最佳实现方式用户无需担心如何访问数据库这类底层问题。此外因为所有应用的数据都集中在一个数据库中查询与联表变得非常容易。1.2 微服务架构下的数据访问困境然而在微服务架构中数据访问变得非常复杂关键在于数据是微服务私有的唯一可访问的方式是通过 API。这种打包数据访问的方式使微服务之间松耦合、彼此独立。如果多个服务访问同一个数据schema 更新将牵一发而动全身需要在所有服务之间进行协调。更甚者不同的微服务经常使用不同的数据库。应用会生产各种不同类型的数据关系型数据库并不一定是最佳选择——某些场景下某个 NoSQL 数据库可能提供更方便的数据模型、更佳的性能和可扩展性。例如产生和查询字符串的应用适合采用 Elasticsearch 这类字符搜索引擎产生社交图片数据的应用可以采用 Neo4j 这类图数据库。因此基于微服务的应用一般都使用 SQL 与 NoSQL 结合的数据库即所谓的polyglot persistence混合持久化方法。这一点在本仓库 《微服务译》 中也有呼应微服务倾向于让每个服务管理自己的数据库或使用同一数据库技术的不同实例或完全不同的数据库系统。分区的、polyglot-persistent 架构在存储数据上有许多优势包括松耦合服务、更佳性能和可扩展性但随之而来的是分布式数据管理带来的挑战。1.3 两大核心挑战第一个挑战如何在完成一笔交易的同时保持多个服务之间的数据一致性。以一个在线 B2B 商店为例客户服务维护包括客户信用额度credit lines在内的各种信息订单服务管理订单需要验证某个新订单与客户的信用限制没有冲突。在单体应用中订单服务只需使用 ACID 事务就可以检查可用信用 创建订单一气呵成但在微服务架构下订单表和客户表分别是各服务的私有表如下图所示订单服务不能直接访问客户表只能通过客户服务发布的 API 来访问。虽然也可以使用分布式事务即广为人知的两阶段提交 2PC但2PC 在现代应用中往往不是可选方案根据 CAP 理论必须在可用性Availability和 ACID 一致性Consistency之间做出选择而可用性一般是更好的选择许多现代技术例如许多 NoSQL 数据库本身并不支持 2PC。关于 CAP 定理本仓库 《分布式系统 CAP 定理 P 代表什么含义》 指出分布式系统不可能同时满足一致性、可用性与分区容错性三点。因此在服务和数据库之间维护数据一致性是非常根本的需求必须寻找其他方案。第二个挑战如何完成从多个服务中搜索数据。例如应用需要显示客户及其订单订单服务提供 API 接受用户订单信息用户可以采用类应用型的 join 操作接收数据——先从用户服务接收用户信息再从订单服务接收该用户的订单。但假设订单服务只支持通过私有键key查询订单例如使用了只支持基于主键访问的 NoSQL 数据库此时就没有合适的方法来接收所需数据。二、事件驱动架构Event-Driven Architecture2.1 基本思想对许多应用来说解决上述问题的方案就是事件驱动架构。在这种架构中当某件重要事情发生时例如更新一个业务实体微服务会发布一个事件当订阅这些事件的微服务接收到事件时就可以更新自己的业务实体也可能会引发更多的事件发布。事件可以用来实现跨多个服务的业务交易。交易一般由一系列步骤构成每一步都由一个更新业务实体的微服务和发布激活下一步骤的事件构成。下面以创建订单时检查信用可用度为例微服务通过**消息代理Message Broker**来交换事件订单服务创建一个带有NEW状态的 Order订单发布一个 Order Created Event创建订单 事件客户服务消费 Order Created Event 事件为此订单预留信用发布 Credit Reserved Event信用预留 事件订单服务消费 Credit Reserved Event将订单状态改变为OPEN。更复杂的场景可以引入更多步骤例如在检查用户信用的同时预留库存等。2.2 弱确定性BASE 模型与最终一致性考虑整个过程的性质a每个服务原子性地更新数据库并发布事件b消息代理确保事件至少传递一次。由此可以跨多个服务完成业务交易——但此交易不是 ACID 事务。这种模式提供弱确定性例如最终一致性eventual consistency这种交易类型被称作BASE 模型。对应地本仓库 《分布式事务》 中介绍的本地消息表等方案同样是以本地事务 消息的机制换取最终一致性与本文事件驱动思想一脉相承。2.3 用事件维护预连接pre-join视图事件还可以用于维护不同微服务拥有数据的预连接pre-join实现视图维护该视图的服务订阅相关事件并更新视图。例如客户订单视图更新服务负责维护客户订单视图会订阅由客户服务和订单服务发布的事件当客户订单视图更新服务收到客户或订单事件时就更新客户订单视图数据集。可以使用文档数据库例如 MongoDB来实现客户订单视图为每个用户存储一个文档客户订单视图查询服务则负责响应对客户以及最近订单的查询通过查询客户订单视图数据集。2.4 事件驱动架构的优缺点优点可以使事务跨多个服务且提供最终一致性可以使应用维护最终视图。缺点编程模式比 ACID 事务模式更复杂为了从应用层级失效中恢复需要完成补偿性事务——例如如果信用检查不成功则必须取消订单应用必须应对不一致的数据临时in-flight事务造成的改变是可见的读取未更新的最终视图时也会遇到数据不一致问题订阅者必须检测和忽略冗余事件消息代理至少一次投递带来的重复事件。三、原子操作Achieving Atomicity事件驱动架构还会遇到数据库更新与发布事件的原子性问题。例如订单服务必须向ORDER表插入一行然后发布 Order Created 事件这两个操作需要原子性。如果更新数据库后服务崩溃crashes导致事件未能发布系统就变成不一致状态。确保原子操作的标准方式是使用一个包含数据库和消息代理的分布式事务但基于前文所述的 CAP 理论这并非我们想要的。下面介绍三种替代方案。3.1 使用本地事务发布事件数据库充当消息队列获得原子性的一个方法是采用仅涉及本地事务的多步骤过程multi-step process involving only local transactions。技巧在于一个EVENT 表——它在存储业务实体的数据库中充当消息列表功能应用发起一个本地数据库事务更新业务实体状态向EVENT表中插入一个事件提交此次事务另一个独立的应用程序进程或线程查询EVENT表向消息代理发布事件使用本地事务标志此事件为已发布。以订单服务为例向ORDER表插入一行再向EVENT表中插入 Order Created 事件事件发布线程/进程查询EVENT表、取出未发布事件、发布它们然后更新EVENT表将其标记为已发布。优点确保事件发布不依赖 2PC应用发布的是业务层级事件无需推断发生了什么。缺点开发人员必须牢记要发布事件因此可能出现人为错误对于某些使用 NoSQL 数据库的应用是个挑战因为 NoSQL 本身的事务和查询能力有限。值得说明的是本仓库 《分布式事务》 中介绍的ebay 本地消息表方案与本节思路高度一致A 系统在本地事务中同时插入业务数据和消息表记录再通过 MQ 发送给 B 系统由定时扫描重发机制保证最终一致性。3.2 挖掘数据库交易日志Transaction Log Tailing另一种不需要 2PC 而获得线程/进程发布事件原子性的方式是挖掘数据库事务或提交日志应用更新数据库在数据库事务日志中产生变化交易日志挖掘进程或线程读取这些交易日志将变化以事件方式发布给消息代理。经典案例LinkedIn Databus 项目Databus 挖掘 Oracle 交易日志根据变化发布事件。LinkedIn 使用 Databus 来保证系统内各记录之间的一致性。AWS DynamoDB 的 Streams 机制DynamoDB 是一个可管理的 NoSQL 数据库DynamoDB Streams 提供过去 24 小时内对数据库表基于时序的变化创建、更新和删除操作应用可以从流中读取这些变化再以事件方式发布。优点确保每次更新发布事件都不依赖 2PC通过将发布事件和应用业务逻辑分离使实现得到简化。缺点交易日志对不同数据库、甚至不同数据库版本都有不同格式很难从底层交易日志的更新记录转换为高层业务事件。3.3 使用事件源Event Sourcing事件源Event Sourcing通过一种根本不同的事件中心方式来获得无需 2PC 的原子性并保证业务实体的一致性。关键转变在于这种应用保存的是业务实体一系列状态改变的事件而不是存储实体当前的状态。应用可以通过重放事件来重建实体的当前状态。只要业务实体发生变化新事件就会追加到事件时间表中。因为保存事件是单一操作因此它必然是原子性的。为了理解事件源的工作方式以订单实体为例传统方式中每个订单映射为ORDER表中的一行例如在ORDER_LINE_ITEM表中而在事件源方式下订单服务以状态改变事件的形式存储一个订单已创建、已批准、已发货、已取消——每个事件都包含足够的数据来重建订单状态。事件被长期保存在**事件数据库事件存储**中它提供 API 来添加和获取实体事件。事件存储与之前描述的消息代理类似也提供 API 来订阅事件将事件递送到所有感兴趣的订阅者——事件存储是事件驱动微服务架构的基干。优点解决了事件驱动架构的关键问题只要有状态变化就可以可靠地发布事件从而解决微服务架构中的数据一致性问题因为是持久化事件而不是对象避免了对象-关系阻抗失配问题object relational impedance mismatch problem提供 100% 可靠的业务实体变化监控日志使得获取任何时点实体的状态成为可能业务逻辑可以由事件交换的松耦合业务实体构成使单体应用移植到微服务架构相对容易。缺点采用不同或不熟悉的编程模式重新学习成本较高事件存储只支持按主键查询业务实体必须使用CQRS命令查询职责分离来完成查询业务应用必须处理最终一致数据。四、总结方案选型与核心脉络在微服务架构中每个微服务都有自己私有的数据集不同微服务可能使用不同的 SQL 或 NoSQL 数据库。尽管这种数据库架构有很强的优势但也面临数据分布式管理的挑战第一个挑战如何在多服务之间维护业务事务一致性第二个挑战如何从多服务环境中获取一致性的数据。最佳解决思路是采用事件驱动架构而其中碰到的关键难题是如何原子性地更新状态并发布事件。解决此问题主要有三种方法可归纳如下方案核心机制主要优点主要缺点本地事务 EVENT 表本地事务内更新实体并写入事件表独立进程轮询发布不依赖 2PC发布业务级事件依赖开发者记得发布事件NoSQL 场景受限交易日志挖掘挖掘数据库事务/提交日志并转发给消息代理不依赖 2PC与业务逻辑解耦日志格式随数据库/版本而异底层记录难转高层业务事件事件源Event Sourcing只追加存储状态改变事件可重放重建状态天然原子、可靠事件流、规避阻抗失配编程模式新、需配合 CQRS、需处理最终一致数据在面试中可以结合本仓库其他章节如 分布式事务、CAP 定理、微服务通讯方式进行联动回答先点明单体 ACID 与微服务私有数据集的矛盾再引出事件驱动架构与最终一致性最后针对原子性难题展开三种方案的对比即可构成一个逻辑完整、层次分明的答案体系。【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/gh_mirrors/ad/advanced-java创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

大唐杯5G仿真网络认知:拓扑、信令与故障排查实战 2026/9/18 16:59:56

大唐杯5G仿真网络认知:拓扑、信令与故障排查实战

第一次打开大唐杯的仿真软件,满屏的网元图标连在一起,线比蜘蛛网还密,我当时的第一反应是——这玩意儿跟我课本上背的"5G网络架构图"完全不是一回事。课本上画的是一个框图,软件里给你的是一个可以点、可以改、可以弄坏…

阅读更多 →
Robot Framework安装避坑指南:环境配置、测试库与浏览器驱动 2026/9/18 16:59:56

Robot Framework安装避坑指南:环境配置、测试库与浏览器驱动

1. 先想清楚一个问题:我们要装的“Robot Framework”到底是个什么很多初学者在搜索引擎里敲下“Robot Framework安装教程”,然后照着文章噼里啪啦复制几条命令,装完一运行发现各种报错,立刻就开始怀疑自己是不是手残。我先说一个可…

阅读更多 →
生成式短文本摘要:基于BiRNN与注意力机制的改进方案与工程实践 2026/9/18 16:59:56

生成式短文本摘要:基于BiRNN与注意力机制的改进方案与工程实践

简介:面向深度学习与自然语言处理方向的参考文献《基于深度学习的文本自动摘要方案》以PDF格式收录,专注解决生成式文本摘要中语义理解不足、语句不通顺与准确度不够高等问题,适合NLP研究者、算法工程师及相关专业学生参考。方案提出改进的词…

阅读更多 →
麒麟V10 SP3 ARM64上运行Oracle 19c的可行性与替代方案 2026/9/18 16:59:56

麒麟V10 SP3 ARM64上运行Oracle 19c的可行性与替代方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Java Swing 汉诺塔图形课设:六类拆分与递归自动演示 2026/9/18 16:59:56

Java Swing 汉诺塔图形课设:六类拆分与递归自动演示

简介:这份资源是面向Java初学者与高校课程设计学生的汉诺塔(Hannoi塔)游戏课程设计报告,围绕递归算法与Swing图形界面开发展开,适合正在完成Java程序设计课程设计、需要参考完整项目实现思路与文档写作规范的读者。包内…

阅读更多 →
Java学生成绩管理系统课程设计:JDBC+MySQL+Swing实战 2026/9/18 16:56:55

Java学生成绩管理系统课程设计:JDBC+MySQL+Swing实战

简介:一份Java学生成绩管理系统课程设计报告,面向计算机、软件工程等专业需要完成课程设计或毕业设计的学生与开发者。文档完整展示了一个基于C/S模式的学生成绩管理系统的设计过程,涵盖学生信息管理、课程成绩维护、按学号或姓名查询、分数段…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞