mirror of
https://github.com/doocs/advanced-java.git
synced 2024-12-24 03:50:08 +08:00
docs(micro-services): fix event-driven-data-management-for-microservices.md
This commit is contained in:
parent
50b066de0f
commit
967a81f6e9
@ -4,10 +4,10 @@
|
||||
|
||||
1. 原子性 – 任何改变都是原子性的
|
||||
2. 一致性 – 数据库状态一直是一致性的
|
||||
3. 隔离性 – 即使交易并发执行,看起来也是串行的
|
||||
4. Durable – 一旦交易提交了就不可回滚
|
||||
3. 隔离性 – 即使事务并发执行,看起来也是串行的
|
||||
4. Durable – 一旦事务提交了就不可回滚
|
||||
|
||||
鉴于以上特性,应用可以简化为:开始一个交易,改变(插入,删除,更新)很多行,然后提交这些交易。
|
||||
鉴于以上特性,应用可以简化为:开始一个事务,改变(插入,删除,更新)很多行,然后提交这些事务。
|
||||
|
||||
使用关系型数据库带来另外一个优势在于提供 SQL(功能强大,可声明的,表转化的查询语言)支持。用户可以非常容易通过查询将多个表的数据组合起来,RDBMS 查询调度器决定最佳实现方式,用户不需要担心例如如何访问数据库等底层问题。另外,因为所有应用的数据都在一个数据库中,很容易去查询。
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
更复杂的场景可以引入更多步骤,例如在检查用户信用的同时预留库存等。
|
||||
|
||||
考虑到(a)每个服务原子性更新数据库和发布事件,然后,(b)消息代理确保事件传递至少一次,然后可以跨多个服务完成业务交易(此交易不是 ACID 交易)。这种模式提供弱确定性,例如最终一致性 eventual consistency。这种交易类型被称作 BASE model。
|
||||
考虑到(a)每个服务原子性更新数据库和发布事件,然后,(b)消息代理确保事件传递至少一次,然后可以跨多个服务完成业务交易(此交易不是 ACID 事务)。这种模式提供弱确定性,例如最终一致性 eventual consistency。这种交易类型被称作 BASE model。
|
||||
|
||||
亦可以使用事件来维护不同微服务拥有数据预连接(pre-join)的实现视图。维护此视图的服务订阅相关事件并且更新视图。例如,客户订单视图更新服务(维护客户订单视图)会订阅由客户服务和订单服务发布的事件。
|
||||
|
||||
@ -55,13 +55,13 @@
|
||||
|
||||
当客户订单视图更新服务收到客户或者订单事件,就会更新 客户订单视图数据集。可以使用文档数据库(例如 MongoDB)来实现客户订单视图,为每个用户存储一个文档。客户订单视图查询服务负责响应对客户以及最近订单(通过查询客户订单视图数据集)的查询。
|
||||
|
||||
事件驱动架构也是既有优点也有缺点,此架构可以使得交易跨多个服务且提供最终一致性,并且可以使应用维护最终视图;而缺点在于编程模式比 ACID 交易模式更加复杂:为了从应用层级失效中恢复,还需要完成补偿性交易,例如,如果信用检查不成功则必须取消订单;另外,应用必须应对不一致的数据,这是因为临时(in-flight)交易造成的改变是可见的,另外当应用读取未更新的最终视图时也会遇见数据不一致问题。另外一个缺点在于订阅者必须检测和忽略冗余事件。
|
||||
事件驱动架构也是既有优点也有缺点,此架构可以使得事务跨多个服务且提供最终一致性,并且可以使应用维护最终视图;而缺点在于编程模式比 ACID 事务模式更加复杂:为了从应用层级失效中恢复,还需要完成补偿性事务,例如,如果信用检查不成功则必须取消订单;另外,应用必须应对不一致的数据,这是因为临时(in-flight)事务造成的改变是可见的,另外当应用读取未更新的最终视图时也会遇见数据不一致问题。另外一个缺点在于订阅者必须检测和忽略冗余事件。
|
||||
|
||||
# 1.3 原子操作 Achieving Atomicity
|
||||
|
||||
事件驱动架构还会碰到数据库更新和发布事件原子性问题。例如,订单服务必须向 ORDER 表插入一行,然后发布 Order Created event,这两个操作需要原子性。如果更新数据库后,服务瘫了(crashes)造成事件未能发布,系统变成不一致状态。确保原子操作的标准方式是使用一个分布式交易,其中包括数据库和消息代理。然而,基于以上描述的 CAP 理论,这却并不是我们想要的。
|
||||
事件驱动架构还会碰到数据库更新和发布事件原子性问题。例如,订单服务必须向 ORDER 表插入一行,然后发布 Order Created event,这两个操作需要原子性。如果更新数据库后,服务瘫了(crashes)造成事件未能发布,系统变成不一致状态。确保原子操作的标准方式是使用一个分布式事务,其中包括数据库和消息代理。然而,基于以上描述的 CAP 理论,这却并不是我们想要的。
|
||||
|
||||
## 1.3.1 使用本地交易发布事件
|
||||
## 1.3.1 使用本地事务发布事件
|
||||
|
||||
获得原子性的一个方法是对发布事件应用采用 multi-step process involving only local transactions,技巧在于一个 EVENT 表,此表在存储业务实体数据库中起到消息列表功能。应用发起一个(本地)数据库交易,更新业务实体状态,向 EVENT 表中插入一个事件,然后提交此次交易。另外一个独立应用进程或者线程查询此 EVENT 表,向消息代理发布事件,然后使用本地交易标志此事件为已发布,如下图所示:
|
||||
|
||||
@ -105,6 +105,6 @@ Event sourcing (事件源)通过使用根本不同的事件中心方式来
|
||||
|
||||
# 1.4 总结
|
||||
|
||||
在微服务架构中,每个微服务都有自己私有的数据集。不同微服务可能使用不同的 SQL 或者 NoSQL 数据库。尽管数据库架构有很强的优势,但是也面对数据分布式管理的挑战。第一个挑战就是如何在多服务之间维护业务交易一致性;第二个挑战是如何从多服务环境中获取一致性数据。
|
||||
在微服务架构中,每个微服务都有自己私有的数据集。不同微服务可能使用不同的 SQL 或者 NoSQL 数据库。尽管数据库架构有很强的优势,但是也面对数据分布式管理的挑战。第一个挑战就是如何在多服务之间维护业务事务一致性;第二个挑战是如何从多服务环境中获取一致性数据。
|
||||
|
||||
最佳解决办法是采用事件驱动架构。其中碰到的一个挑战是如何原子性的更新状态和发布事件。有几种方法可以解决此问题,包括将数据库视为消息队列、交易日志挖掘和事件源。
|
||||
|
Loading…
Reference in New Issue
Block a user