【问题标题】:How to model aggregates relations with Akka如何使用 Akka 建模聚合关系
【发布时间】:2020-09-11 08:30:33
【问题描述】:

我在演员模型中的关系中挣扎。让我用一个简单的例子。系统中有两种参与者类型:仓库和项目。物料总是分配给特定的仓库。 AddStock 命令允许增加分配给给定仓库位置的库存数量。只有仓库知道自己的位置,因此项目必须询问其仓库该位置是否有效以执行自己的业务逻辑。我已经想到了一些解决方案

  1. AddStock 命令包含仓库分片区域的 ActorRef,它允许 Item 向 Warehouse 询问位置。
  2. 以某种方式仅允许仓库发出命令 AddStock,该命令允许预先验证位置。不知道如何实现这一点,我考虑过私人命令或一些识别过程

我不喜欢这两种解决方案。它为简单的任务增加了许多不必要的复杂性。我认为这里的 OOP 思维可能存在问题,分布式 Actor 世界受其自身规则的约束。

在我的场景中,我将 Item 和 Warehouse 视为单独的集合。它们都被实现为 Persistent Actor(使用集群分片)。

只要您假设只有 Warehouse 可以调用 Item::AddStock,一切都很容易。然后 Warehouse 只是在调用之前验证位置。但是可以直接调用 Item 并跳过所有验证。项目无法知道是否是正确的仓库发出了呼叫。在纯 OOP/DDD 方法中很容易实现。项目知道仓库 ID,更改数量看起来像这样

item.addStock("L2", 100, warehouse)

知道仓库 ID 的项目可以验证提供的仓库是否是仓库。并且有仓库可能会询问位置是否有效。我当前的项目处理程序实现:

case AddStock(region, location, quantity) => {
  region ? EntityEnvelope(warehouseId, HasLocation(location)) map (
    _ => VerifiedAddStock(quantity)
  ) pipeTo self

VerifiedAddStock 是 Item 的私有对象,所以我确定谁是命令发出者(几乎是因为它不强制标识)。

那么问题是如何在 Actor 世界中建模这种关系?绕过shard region ref是常态吗?

有人可能会认为这是由于聚合/参与者边界不当造成的设计缺陷本身,但这只是一个示例。

【问题讨论】:

    标签: java scala concurrency akka actor


    【解决方案1】:

    Item 是否有任何 Warehouse 不会关心的信息(例如描述)?

    如果答案是否定的,那么我只会将 Item 视为关联仓库位置的子项(即反转关系的方向)。只要仓库从不为 Item 提供 ActorRef,您就可以确定只有它可以向 Item actor 发送消息(Akka Typed 可以让您做出这种静态保证)。

    如果答案是肯定的,我建议在仓库库存的上下文中,一个项目完全由该上下文所需的信息组成,例如,目录描述之类的内容是不同上下文的责任(非常可能是不同的服务)并且如果目录描述上下文需要了解有关库存的某些信息(例如,它是否在任何地方有库存),那么它应该利用仓库库存发出的域事件。

    【讨论】:

    • 我喜欢你的建议。多亏了它,我想出了使 Item 成为 Warehouse 内部私有类的想法。所以我确信只有 Warehouse 可以与 Item 联系。这种方法的缺点是不能将类拆分为单独的文件。也许将 Warehouse 和 Item 包装成包(并将 Item 设为私有)就可以了。
    猜你喜欢
    • 1970-01-01
    • 2016-03-28
    • 2019-09-20
    • 2014-08-05
    • 2015-06-20
    • 1970-01-01
    • 2015-09-05
    • 2013-11-24
    • 1970-01-01
    相关资源
    最近更新 更多