【发布时间】:2019-09-23 11:40:57
【问题描述】:
我正在尝试为我公司处理订单管理的一些简单内部系统设置一个实用的微服务演示,但是我很难理解大规模微服务之间的数据一致性。
我已经为微服务确定了一个简单的场景 - 我们正在运行的当前应用程序在我们的网站上处理订单并更新客户的“帐户信用”时接受订单 - 基本上是他们可以在他们的帐户之前在我们那里花费的未付款项需要审核。
我试图将这个非常简单的需求分解为几个微服务。它们的定义如下:
API 提供各种不同级别的功能 - 它允许我们创建新客户,这会触发以下操作:
使用SQL,我们可以在数据库内工作时做一些乐观查询,通过扩展微服务(EG:Order Microservice的两个实例,每个微服务,但不微服务的每个实例都有自己的数据库)。
例如,我们可以执行以下操作并假设 SQL 将管理锁定,这意味着当同时处理两个订单时,数字应该以正确的数字结束:
UPDATE [orderms].[customers] SET CreditLimit = CreditLimit - 100, NoOfOrders = NoOfOrders + 1 WHERE CustomerId = 1
根据上述情况,如果信用是 1000,并且处理了 2 个 100 的订单,并且每个订单被分配到“订单”微服务的不同实例,我们应该能够假设正确的数字将出现在订单微服务中的客户表(基于 MSSQL 查询的锁定应自动处理此问题)。
当我们尝试将它们集成回客户微服务时,问题就来了。我们将有两条消息,来自订单微服务的每个实例,作为事件传递,示例如下:
鉴于上述情况 - 我们很可能会按照以下方式更新“客户”SQL 表(这是两个查询):
UPDATE [customerms].[customers] SET CreditLimit = 900.00 WHERE CustomerId = 1
UPDATE [customerms].[customers] SET CreditLimit = 800.00 WHERE CustomerId = 1
但是 - 根据这些“客户”微服务的运行速度,实例 #1 目前可能正在创建多个新客户,因此处理此请求的速度可能比实例 #2 慢,这意味着 SQL 查询将无序执行,因此我们将留下 CreditLimit 为 800(正确)的“Order”数据库和 CreditLimit 为 900(不正确)的客户微服务。
在单体应用程序中,如果确实需要,我们通常会添加一个锁定元素(或可能是互斥锁),否则将根据订单微服务中的功能依赖 SQL 锁定,但由于这是一个分布式过程,这些旧方法都不适用。
有什么建议吗?我似乎无法以某种方式看到过去?
【问题讨论】: