微服务之间的跨服务依赖

7
为了简化我的情况,我目前有三个微服务:
  1. 认证
  2. 位置
  3. 库存
认证服务对用户进行身份验证,并返回JWT访问令牌,我在其他服务中使用它。它是无状态的,一切都很顺利。
我在位置服务中设置了位置等内容,这也很好地按预期工作。
但现在我正在处理库存服务,我需要添加一些库存,但它与某个位置相关联。我可以轻松地通过API调用传递locationId,但我没有办法授权当前用户向该位置添加物品,除非我调用位置服务进行验证。
这将在各个服务之间创建服务依赖关系,这是我尽力避免的事情,否则您将失去大部分微服务的好处。
那么,验证当前用户是否具有该位置的权限的推荐方法是什么呢?我迄今想到的唯一方法是:
  1. 让位置API发放另一个访问令牌,其中包含他们可以访问的其他位置的附加声明。
  2. 或者发放另一个完全独立的令牌,并通过标头将其传递给库存微服务,以进行类似于JWT身份验证的验证。
编辑:
如下所述,提供聚合根(或我假设与API网关相同)将提供第三种选项,即另一个服务在顶部通信以提供信息。
但是,它会留下一个依赖于两个其他服务的第三个服务,这样我就增加了我的服务依赖性。

在谷歌上搜索“聚合”和“聚合根”。它是一个适用于微服务的事务元素,非常完美。 - jlvaquero
3个回答

8
您的微服务设计很差。您将(locationitems)1类=1微服务建模,这不是一个好主意。
您应该像DDD中的聚合根一样建模微服务;即使有自己的界限上下文。因此,在您的情况下,您应该建模具有位置物品用户聚合根,以允许在添加物品用户操作时检查域规则。这可以在您的库存上下文中实现。
当然,这并不意味着您不应该有一个仓库上下文,其中您可以添加,修改和/或删除位置,如果没有需要检查域规则的依赖关系,则聚合根只是位置类。但这是另一个上下文中的其他微服务。
这篇文章应该会对您有所帮助。阅读后,您的思维将得到大大的启发。

我没有将一个类建模为一个微服务。每个服务处理自己的领域,有许多表,但逻辑上分组处理特定的功能。位置和库存与之相关联的模型有几个。但是它们之间存在依赖关系。位置服务还将处理与库存无关的应用程序其他部分的基于位置的服务。 - Adam
只是想补充说明一下,这个示例真的很简化,这样我才能突出跨服务依赖的方面。当我看到跨服务依赖时,我首先想到的是应该将它们组合在一起,但并不是所有情况都可以这样做,否则我就会将库存、位置和其他服务全部合并成一个大型单块API,所有东西都混在一起。 - Adam
我将把库存、位置和其他服务合并为一个。我的观点不是合并服务,而是从持久性中获取聚合根,并提供仅涉及此聚合根的用例的单个微服务。 - jlvaquero
当然,这会引起很多关于如何处理持久性的问题;所有微服务使用相同的持久性系统?分为读写模型?每个服务独立的写模型和一个读模型?等等。当然,这取决于您的系统和要求。微服务之旅漫长且需要大量时间和工作,直到所有事情都匹配起来。 - jlvaquero

0
虽然@jlvaquero上面提供了想法,但我只是想列出我的实际解决方案及其原因。
然后就到了这个设置。

enter image description here

现在验证是在网关级别完成的。我唯一不确定的事情是,我现在正在对一个实体进行验证,而该实体位于应该负责该域的服务之外。

库存服务只是接受用户被允许添加到该位置。但考虑到位置和用户验证是服务域外的,因此它不应该涉及该验证。


如果我可以问一下,我也已经开始使用微服务模式了。我能向您请教一些建议吗?我在这里发布了一个问题:https://dev59.com/xZPea4cB1Zd3GeqP9wYG - Tez Wingfield

0

网关只应进行身份验证,而不是授权。 授权在服务内部处理,因为服务仅维护谁可以访问它。 我将获取库存服务以获取用户被授权访问的位置列表。

整个编排将在 UI 级别进行,以便库存服务不会对位置服务建立硬依赖。

这是一种方法-不确定是否适用于您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接