【问题标题】:Decomposition into microservices分解成微服务
【发布时间】:2017-11-07 16:25:12
【问题描述】:

我有一个关于分解成微服务的问题。假设我们有 2 个微服务:UserProduct。假设我们现在需要向系统添加类别。更具体地说,一个产品有一个或多个类别(例如产品红色微型法拉利属于玩具和汽车类别),用户可以拥有她喜欢的类别(例如玩具和鞋子)。现在,当我们检索完整的产品列表时,我们希望对它们进行排序,使得属于首选用户类别的产品位于顶部。

基本上是有一个在微服务之间共享的概念(在这种情况下是类别)。如何在微架构环境中对此进行最佳建模?我看到了两种解决方案:

解决方案 1:

  • 创建一个单独的“类别”微服务来管理类别的 CRUD
  • 在产品服务中有一个 API 调用将类别 ID 链接到产品
  • 在用户服务中有一个 API 调用将类别 ID 链接到用户
  • 在产品服务中,我们有一个 API 调用来获取按偏好订购的产品。为此,产品服务需要调用用户服务来获取用户类别(或监听用户服务发出的事件)

解决方案 2:

  • 创建一个单独的“类别”微服务来管理类别的 CRUD

  • 分类服务还有一个 API 调用将产品 ID 链接到分类

  • 分类服务还有一个 API 调用将用户 ID 链接到分类

  • 在产品服务中,我们有一个 API 调用来获取按偏好订购的产品(要使这项工作正常工作,产品服务需要调用类别服务来获取用户和产品类别(或监听事件)

这两种解决方案的优缺点是什么?

【问题讨论】:

    标签: architecture microservices bounded-contexts


    【解决方案1】:

    第 3 种替代解决方案是不将微服务仅制作为表格。仅将具有 CRUD 功能的“事物”放在单独的服务中的问题在于,大多数情况下,它们会有很多交叉依赖关系。这就是你现在遇到的问题。

    您可以制作与功能而非数据一致的服务。做一个“搜索”服务、一个“购物车”服务、“计费”服务等等。所有这些东西通常都需要同一个“东西”(比如产品)的不同方面。例如,我可以想象这些类别仅与“搜索”相关,而与其他两个无关。

    有些人已经写过关于这种方法的文章here, named Self-Contained Systems

    【讨论】:

    • 假设您有一个单独的搜索服务。该服务仍然需要知道哪些产品/用户与哪些类别相关联。哪个服务负责维护此链接?解决方案 1 由链接到类别(例如产品和用户)的服务负责,其中解决方案 2 创建一个单独的微服务来管理需要链接到类别的所有其他服务的此链接。您是否建议搜索服务应维护该链接?如果是这样,哪个服务会创建系统中可用的类别?谢谢澄清。
    • 是的,搜索服务将负责搜索功能所需的用户和产品的类别“视图”。根本不应该有“用户”服务和“产品”服务。
    【解决方案2】:

    我会说你应该有一个更复杂的服务和三个简单的服务。你的分类服务应该只是分类的CRUD,你的用户服务应该是用户的CRUD,你的产品应该更复杂,称之为productlisting服务,然后还有一个简单的产品服务。

    您的产品列表服务应该具有所有的复杂性,但可能是非规范化的。

    GET/POST/PUT/DELETE /product
    GET/POST/PUT/DELETE /category
    GET/POST/PUT/DELETE /user
    
    POST/PUT /productlisting/usercategory/<userid>  <list of categories>
    POST/PUT /productlisting/productcategory/<productid>  <list of categories>
    GET /productlisting
    

    要么这样,要么将它们全部组合成一个整体......它们不是单独的关注点,从长远来看,通过 ID 耦合它们只会让你感到难过,因为你的耦合会很脆弱。我从不让一项服务知道另一项服务的实体 ID。分布式系统中的这种关系约束只是自找麻烦。

    【讨论】:

    • 如果你不在微服务之间共享 id,你最终不会把所有东西都放在单体里吗?我很难想象这样一个微服务架构,其中在微服务之间没有共享上下文(除了简单的“帮助”服务,如电子邮件发送者微服务)。能详细点吗?
    • 它需要接受数据在您的解决方案中重复。您真的不需要连接到产品的类别 ID,您可以使用类别本身。您不需要用户 ID,使用可以安全复制的东西,例如电子邮件地址。将这些视为独立程序,您将获得更好的扩展性和更大的弹性。这将使他们能够独立发展。如果它们真的不能解耦,那么它们就是一个单体,应该这样设计。
    • 构建一个将其模块拆分为单独部署并在它们之间使用有线协议的单体不是微服务,您将承担微服务的所有开销,并且无法实现任何好处。
    【解决方案3】:

    嗯,解决方案 2 已经过时了,因为您将在不同的服务中为很多事情使用类别,并且它会破坏关注点的分离以使类别服务在所有这些不同的域中实现搜索。

    此外,除了类别之外,现实的产品或用户搜索还可以包括其他条件。让所有这些不同条件的服务实现自己的产品搜索通常不是一个好的实现,因为在多条件搜索中合并结果可能会很昂贵,所以这种在定义条件对象的服务中实现搜索的模式确实不是规模。

    解决方案 1 已接近,但没有理由让产品服务知道或致电用户服务。产品服务应该有一个 API,可以使用各种标准(包括类别)搜索产品。通过让客户端传递类别 ID 列表而不是用户 ID 来实现类别搜索可能会更好。那么它就不用自己调用用户服务了,你保持产品和用户服务的独立。此外,按类别搜索产品对于其他事情(例如浏览产品!)很有用,而且由于您没有将类别搜索与用户联系起来,您可以使用相同的 API 来处理其他情况。

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 1970-01-01
      • 2021-09-08
      • 2020-08-27
      • 2019-10-28
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多