【发布时间】:2020-02-20 07:35:21
【问题描述】:
我是微服务的新手。您能否解释一下微服务的事务管理以及不同数据库之间的外键是如何工作的,例如客户端和订单服务有自己的服务和数据库。如果我们使用单个数据库,订单表有一个客户端的外键。但是数据库不同,我们如何在这些表之间放置外键?以及我们如何完成这些服务之间的事务管理? 谢谢
【问题讨论】:
标签: microservices
我是微服务的新手。您能否解释一下微服务的事务管理以及不同数据库之间的外键是如何工作的,例如客户端和订单服务有自己的服务和数据库。如果我们使用单个数据库,订单表有一个客户端的外键。但是数据库不同,我们如何在这些表之间放置外键?以及我们如何完成这些服务之间的事务管理? 谢谢
【问题讨论】:
标签: microservices
在我看来,您正试图通过 ACID 标准解决最终一致的世界。通常有微服务的原因是因为 ACID 不会扩展,否则为什么要有多个数据库?在这一点上,您应该忘记事务,并且非常清楚每个微服务的职责以及它处理的数据。尝试使用非常清晰的键,该键是服务之间的逻辑外键,但不强制执行。
例如,您有两个服务:处理学生操作的 StudentsService 和处理学生日程安排的 ScheduleService。
StudentsService 将拥有可以允许对学生进行多次搜索的学生数据库等。该服务应分配给每个学生的一个重要字段 - 唯一 ID。至少 StudentsService 应该提供以下 API:
现在所有其他服务都必须使用学生 ID 作为学生的标识符。他们不了解这个领域。他们不知道它是否真实(外键意味着检查它是否真实,但它真的很重要吗?)
现在你有点拥有你的外键,但不是真的。
鉴于学生的唯一 ID 绝不能更改 - 绝对没有理由更改它。鉴于它永远不会被删除(现在存储很便宜),你有一个完美的外键。
事务很棘手,如果您想扩展,应该不惜一切代价避免。为什么要交易?您能否拥有客户端可以重试或快速失败的小型幂等操作流程?继续上面的示例,编辑或创建学生将是一项操作,而创建或编辑学生时间表可以是另一项操作。两者之间无需交易。
【讨论】:
微服务领域的分布式数据管理是需要解决的最复杂的问题之一。但是,有一些模式和指南可以帮助解决分布式数据的问题。下面列出了其中一些
定义微服务的有界上下文 - 每个微服务都必须拥有自己的域数据和逻辑。这是您需要打破外键依赖关系并确定您将拥有哪个表以及您将引用哪个表的地方。
ACID 语义的最终一致性 - 如果有两个服务目录和篮子。目录包含产品详细信息,篮子包含用户当前购买的项目。产品价格的任何变化都应反映在购物篮中的项目中。然而,由于产品数据和购物篮项目存储在两个不同的数据库中,价格更新是异步发生的。 这可以通过发布者订阅者模式来实现。例如,价格变化事件发布在消息总线上,Basket 等服务订阅它并在收到事件时自行更新。
使用实体化视图的只读数据存储 - 这是 CQRS 模式的一种形式,其中来自多个服务的数据以非规范化形式存储在只读数据存储中。使用上述方法异步更新数据。消费者无需查询多个服务即可快速访问数据。
总之,对于 CAP 定理,微服务世界更喜欢高性能、可扩展性和可用性,而不是强一致性。最终使用异步通信解决一致性问题。
【讨论】: