微服务: 如何处理外键关系

微服务体系结构建议每个服务应该处理自己的数据。因此,任何依赖于其他服务(服务 B)拥有的数据的服务(服务 A)不应通过直接数据库调用而是通过第二个服务(服务 B)提供的 API 访问这些数据。

那么,微服务最佳实践对检查外键约束有什么建议呢

示例: 我正在为产品开发一个交付特性(微服务1) ,并且某些产品只能交付到产品表中提到的某些位置,只能访问产品微服务(微服务2)。

如何确保微服务1(即交付特性)不会将订单传送到未提供服务的位置。我有这个问题是因为交付特性不能直接访问产品数据库,所以当交付订单放入到交付数据库时,在 DB 级别没有适用的约束(不可能检查产品数据库或表中是否存在外键匹配)。

52281 次浏览

可以对多个微服务使用共享数据库。您可以在这个链接中找到微服务的数据管理模式: http://microservices.io/patterns/data/database-per-service.html。顺便说一下,它是一个非常有用的微服务架构博客。

在您的示例中,您更喜欢按照服务模式使用数据库。这使得微服务更加自治。在这种情况下,您应该在多个微服务之间复制一些数据。您可以在微服务之间通过 api 调用共享数据,也可以通过异步消息传递共享数据。这取决于您的基础设施和数据更改的频率。如果不经常更改,则应使用异步事件复制数据。

在您的示例中,传递服务可以复制传递位置和产品信息。产品服务管理产品和地点。然后,使用异步消息将所需的数据复制到传递服务的数据库(例如,您可以使用 Rabbit mq 或 apache kafka)。配送服务不更改产品和位置数据,但在执行其工作时使用这些数据。如果传递服务使用的产品数据部分经常发生变化,那么使用异步消息传递的数据复制将非常昂贵。在这种情况下,您应该在 Product 和 Deliverservice 之间进行 api 调用。交付服务要求产品服务检查产品是否可以交付到特定位置。传递服务使用产品和位置的标识符(名称、 ID 等)请求 Products 服务。这些标识符可以来自最终用户,也可以在微服务之间共享。由于这里的微服务数据库是不同的,我们不能在这些微服务数据之间定义外键。

Api 调用可能更容易实现,但是这个选项的网络成本更高。此外,在进行 API 调用时,您的服务的自主性也较差。因为,在您的示例中,当 Product service 停止时,传递服务无法完成其工作。如果使用异步消息传递复制数据,则传递所需的数据位于 Deliverymicroservice 数据库中。当产品服务不工作时,你将能够交付。

在分发代码以减少耦合时,您希望避免资源共享,而数据是您希望避免共享的资源。

另一点是,系统中只有一个组件拥有数据(用于状态更改操作) ,其他组件可以读但不能写,它们可以拥有数据的副本,或者你可以共享一个视图模型,它们可以用来获取对象的最新状态。

引入参照完整性会重新引入耦合,相反,你想使用类似 Guids 的东西作为主键,它们将由对象的创建者创建,其余的都是关于管理最终一致性的。

看看 Udi Dahan 的 详情请参阅奥斯陆国家数据中心

希望这个能帮上忙

2020年对这个答案的更新是使用更改数据捕获工具,如 Debezium。Debezium 将监视数据库表的更改,并将其传送到 Kafka/Pulsar (其他管道) ,然后订阅者可以捕获更改并同步它们。

第一个解决方案: 原料药组成

 Implement a query by defining an API Composer, which invoking the
services that own the data and performs an in-memory join of the
results

enter image description here

第二个解决方案: CQRS

Define a view database, which is a read-only replica that is designed to support that
query. The application keeps the replica up to data by subscribing to Domain events
published by the service that own the data.

enter image description here

... 如何确保微服务1(即送货功能)不会将订单送到未提供服务的位置..。

你不是在网上做,而是以延迟的方式。

您的服务 # 1接收订单,执行它自己可以执行的所有验证,并保存它。延迟服务处理订单并在稍后验证其他方面。一旦发现该位置无法使用,它可能会以被拒绝的方式返回。您的服务将需要优雅地告知用户,甚至可能取消订单。