在基于微服务的系统中实现数据库一致性的最佳方法是什么?
在GOTO in Berlin上,Martin Fowler在谈论微服务,他提到的一个“规则”是保留“每个服务”数据库,这意味着服务无法直接连接到另一个服务“拥有”的数据库。
这是超好和优雅的,但实际上它会变得有些棘手。假设您有一些服务:
现在,客户在您的前端进行购买,这将称为订单管理服务,该服务会将所有内容保存在数据库中-没问题。此时,还将有一个忠诚度计划服务 call ,以便它从您的帐户中积分/借记积分。
现在,当所有内容都在同一个DB / DB服务器上时,一切都变得容易了,因为您可以在一个事务中运行所有内容:如果忠诚度计划服务未能写入数据库,我们可以将整个过程回滚。
当我们通过多种服务进行数据库操作时,这是不可能的,因为我们不依赖于一个连接,也不利用运行单个事务的优势。
保持事物一致和幸福生活的最佳方式是什么?
我非常渴望听到您的建议!
最佳答案
它的“实际”含义是,您需要以某种方式设计微服务,以便在遵循规则时可以实现必要的业务一致性:
换句话说-在找到可行的方法之前,不要对他们的职责做任何假设,并根据需要更改界限。
现在,对您的问题:
对于不需要立即一致性的事情,并且更新忠诚度积分似乎属于该类别,您可以使用可靠的发布/预订模式来调度来自一个微服务的事件,以供其他微服务处理。可靠的一点是,您需要对事件处理进行适当的重试,回滚和幂等(或事务处理)。
如果您在.NET上运行,则支持这种可靠性的基础结构示例包括NServiceBus和MassTransit。全面披露-我是NServiceBus的创始人。
更新:以下是有关忠诚度积分的问题的评论:“如果延迟处理余额更新,则客户实际上可能能够订购超出其积分的商品”。
许多人都在为强一致性而满足这些要求。问题在于,通常可以通过引入其他规则来处理这类情况,例如,如果用户最终获得负的忠诚度积分,则可以通知他们。如果T过去了,而忠诚度积分却没有整理出来,请通知用户他们将根据某种转化率向他们收取M的费用。客户使用积分购买商品时,此政策应对客户可见。
关于database - 数据库与微服务的一致性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31104540/