微服务架构:跨服务数据共享

Posted

技术标签:

【中文标题】微服务架构:跨服务数据共享【英文标题】:Microservices Architecture: Cross Service data sharing 【发布时间】:2015-06-10 05:08:01 【问题描述】:

考虑以下用于在线商店项目的微服务: 用户服务保留有关商店用户的帐户数据(包括名字、姓氏、电子邮件地址等)

Purchase Service 跟踪有关用户购买的详细信息。

每个服务都提供一个 UI,用于查看和管理其相关实体。 购买服务索引页面列出了购买。每个采购项目应具有以下字段: id、购买用户全名、购买商品名称和价格。 此外,作为索引页面的一部分,我希望有一个搜索框,让商店经理通过购买用户名搜索购买。

我不清楚如何取回购买服务不保存的数据 - 例如:用户的全名。 当尝试通过购买用户名进行搜索购买等更复杂的事情时,问题会变得更糟。

我想我显然可以通过在用户创建时广播某种事件(并在购买服务端仅保存相关的用户属性)在两个服务之间同步用户来解决这个问题。在我看来,这远非理想。当您拥有数百万用户时,您如何处理这个问题?您会在每个使用用户数据的服务中创建数百万条记录吗?

另一个明显的选择是在用户服务端公开一个 API,它可以根据给定的 id 返回用户详细信息。这意味着购买服务中的每个页面加载,我都必须调用用户服务以获得正确的用户名。不理想,但我可以忍受。

如何实现基于用户名的购买搜索?好吧,我总是可以在接收查询词的用户服务端公开另一个 API 端点,对用户服务中的用户名执行文本搜索,然后返回所有符合条件的用户详细信息。在购买服务中,将相关 id 映射回正确的名称并在页面中显示它们。这种方法也不理想。

我错过了什么吗?是否有另一种实现上述方法的方法?也许我面临这个问题的事实有点代码味道?很想听听其他解决方案。

【问题讨论】:

我对这个问题有点困惑。字体端应用程序应该与服务分开。您应该能够在不更改服务的情况下更改前端应用程序。对于购买屏幕,应调用购买服务和用户服务来获取屏幕数据。或者,可以在服务前面放置一个单独的 api,它将调用这两个服务,然后将数据返回到屏幕。看一下图表here,它显示了它应该如何工作。 这里是 API 模式:microservices.io/patterns/apigateway.html 【参考方案1】:

在进入微服务时,这似乎是一个非常常见和核心的问题。我希望有一个好的答案:-)

关于这里已经提到的建议模式,我将使用术语数据非规范化而不是多语言持久性,因为它不一定需要使用不同的持久性技术。关键是每个服务都处理自己的数据。是的,你有数据重复,你通常需要某种事件总线来跨服务共享数据。

还有另一种选择,这是对第一种选择的一种尝试——将搜索本身作为一个单独的服务。

因此,在您的示例中,您拥有用于管理用户的用户服务。采购服务管理采购。每个都处理自己的数据,并且只处理它需要的数据(例如,Purchase 服务实际上并不需要用户名,只需要 ID)。您还有第三个服务 - 搜索服务 - 使用其他服务生成的数据,并根据组合数据创建搜索“视图”。

【讨论】:

【参考方案2】:

将适当的数据保存在不同的数据库中是完全可以的,它被称为Polyglot Persistence。是的,您希望单独保留用户数据和有关购买的数据,并使用消息队列进行同步。数百万用户对我来说似乎很好,这是可扩展性,而不是设计问题 ;-)

在搜索的情况下 - 您可能想要搜索的不仅仅是用户名,对吧?因此,如果您使用消息队列来更新服务之间的数据,您还可以轻松地将这些数据路由到 ElasticSearch,例如。从 ElasticSearch 的角度来看,索引哪个字段并不重要——用户名或产品标题。

【讨论】:

【参考方案3】:

我通常同时使用这两种方法。有时我有另一个服务位于 x 其他服务之上并组合数据。我不太喜欢这种方法,因为它会导致服务之间的依赖和耦合。所以总的来说,在我最近的项目中,我们试图坚持多语言持久性。

另外想想,如果你需要有 x 个 sub http 请求来组合某种中间件服务中的数据,它会导致你的延迟更高。我们总是试图减少一项任务的请求数量,并通过异步队列处理所有可能的事情。 (尤其是数据同步)

【讨论】:

【参考方案4】:

如果您将模块概念化为它们处理的数据的所有者和控制者,那么您的模型还必须将该模块中的数据传递给其他人。相比之下,制造过程中的模块可以访问更改数据,而无需拥有和控制它。

微服务是一种用于分布式处理的架构,就像大多数代码一样,模块在其中传递数据以处理它。从《哈佛商业评论》和麦肯锡关于拥有供应链成员的经典文章中,我发现了这种模型带来的复杂性,并写了一篇文章教程序员你需要知道的事情:http://www.powersemantics.com/p.html

制造是一种用于集成处理的架构,其中模块处理数据而不用点对点传递。这可以通过将模块配置为访问相同的内存、文件或数据库表来实现。我的架构展示了如何通过引用属性在内存上实现这一点。

当您考虑“在用户服务端公开一个基于给定 ID 带回用户详细信息的 API”时,您需要注意这会产生 HBR 所谓的“不可逆”复杂性,我称之为中心化复杂性。不要构建 A->B(分布式)系统,因为您无法在未能分离需求后将它们分散。生产过程中的需求代表用户的指令,集中的模块只能让你改变错误的用户的过程。换句话说,集中式模块不会记录用户组或将它们与派生产品用户区分开来。

【讨论】:

以上是关于微服务架构:跨服务数据共享的主要内容,如果未能解决你的问题,请参考以下文章

「微服务架构」跨多个微服务的数据架构模式

微服务架构 | 服务之间跨域问题怎么解决?

使用 Django REST 框架跨微服务共享数据库关系

基于OpenResty和Node.js的微服务架构实践

基于OpenResty和Node.js的微服务架构实践

个推首席架构师俞锋锋:基于OpenResty和Node.js的微服务架构实践