Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 数据库与微服务的一致性_Database_Soa_Microservices - Fatal编程技术网

Database 数据库与微服务的一致性

Database 数据库与微服务的一致性,database,soa,microservices,Database,Soa,Microservices,在基于微服务的系统中,实现数据库一致性的最佳方法是什么 在会议上,Martin Fowler谈到了微服务,他提到的一条“规则”是保留“每服务”数据库,这意味着服务不能直接连接到另一个服务“拥有”的数据库 这是非常好和优雅,但在实践中它变得有点棘手。假设您有一些服务: 前端 订单管理服务 忠诚计划服务 现在,客户在您的前端进行购买,这将调用订单管理服务,它将保存数据库中的所有内容--没问题。此时,还将呼叫忠诚度计划服务,以便其从您的帐户贷记/借记积分 现在,当所有内容都在同一个DB/DB服务器

在基于微服务的系统中,实现数据库一致性的最佳方法是什么

在会议上,Martin Fowler谈到了微服务,他提到的一条“规则”是保留“每服务”数据库,这意味着服务不能直接连接到另一个服务“拥有”的数据库

这是非常好和优雅,但在实践中它变得有点棘手。假设您有一些服务:

  • 前端
  • 订单管理服务
  • 忠诚计划服务
现在,客户在您的前端进行购买,这将调用订单管理服务,它将保存数据库中的所有内容--没问题。此时,还将呼叫忠诚度计划服务,以便其从您的帐户贷记/借记积分

现在,当所有内容都在同一个DB/DB服务器上时,一切都变得很容易,因为您可以在一个事务中运行所有内容:如果忠诚度计划服务无法写入DB,我们可以回滚整个事务

当我们在多个服务中执行DB操作时,这是不可能的,因为我们不依赖一个连接/不利用运行单个事务的优势。 保持事物一致并过上幸福生活的最佳模式是什么


我很想听听你的建议!。。提前谢谢你

我通常不处理微服务,这可能不是一种好的做事方式,但这里有一个想法:

为了重申这个问题,该系统由三个独立但相互通信的部分组成:前端、订单管理后端和忠诚度计划后端。前端希望确保订单管理后端和忠诚度计划后端都保存了一些状态

一种可能的解决方案是实施某种类型的:

  • 首先,前端将一条记录和所有数据放在自己的数据库中。称之为前端记录
  • 前端向订单管理后端请求事务ID,并向其传递完成操作所需的任何数据。订单管理后端将此数据存储在暂存区域中,与之关联一个新的事务ID并将其返回到前端
  • 订单管理事务ID存储为前端记录的一部分
  • 前端向忠诚度计划后端请求事务ID,并向其传递完成操作所需的任何数据。忠诚度计划后端将此数据存储在暂存区域中,与之关联一个新的事务ID,并将其返回到前端
  • 忠诚度计划交易ID作为前端记录的一部分存储
  • 前端通知订单管理后端完成与前端存储的事务ID关联的事务
  • 前端通知忠诚度计划后端完成与前端存储的交易ID关联的交易
  • 前端删除其前端记录
  • 如果实现了这一点,更改不一定是原子性的,但最终将是一致的。让我们想想它可能失败的地方:

    • 如果第一步失败,则不会更改任何数据
    • 如果在第二次、第三次、第四次或第五次失败,当系统重新联机时,它可以扫描所有前端记录,查找没有关联交易ID(任何一种类型)的记录。如果它遇到任何这样的记录,它可以从步骤2开始重放。(如果在步骤3或5中出现故障,则在后端会留下一些废弃的记录,但不会将其移出暂存区域,因此一切正常。)
    • 如果在第六步、第七步或第八步失败,当系统重新联机时,它可以查找所有前端记录,并填写两个事务ID。然后,它可以查询后端以查看这些已提交或未提交事务的状态。根据已提交的文件,它可以从相应的步骤恢复
    这是非常好和优雅,但在实践中它变得有点棘手

    “在实践中”的意思是,您需要以这样一种方式设计您的微服务,即在遵循规则时满足必要的业务一致性:

    该服务不能直接连接到另一个服务“拥有”的数据库

    换言之,不要对他们的职责做出任何假设,在你找到一种可行的方法之前,根据需要改变界限

    现在,回答你的问题:

    保持事物一致并过上幸福生活的最佳模式是什么

    对于不需要立即一致性的事情,并且更新忠诚度点似乎属于这一类,您可以使用可靠的发布/订阅模式从一个微服务发送事件供其他微服务处理。可靠的一点是,您需要良好的重试、回滚和事件处理的幂等性(或事务性)

    如果您在.NET上运行,一些支持这种可靠性的基础设施示例包括和。充分披露-我是NServiceBus的创始人

    更新:以下关于忠诚度积分关注点的评论:“如果余额更新延迟处理,客户实际上可能能够订购超过其积分的商品”


    许多人都在为实现强一致性而挣扎。问题是,这类场景通常可以通过引入额外的规则来处理,比如如果用户最终获得负忠诚度点数,通知他们。如果T过去而没有整理忠诚积分,则通知用户将根据某个转换率向他们收取M。当客户使用积分购买物品时,此政策应该对他们可见。

    我同意@Udi Dahan的说法。只是想补充一下他的答案

    我认为你需要坚持这个原则