通过持久性ID查找演员

时间:2018-11-07 15:12:41

标签: scala akka akka-persistence akka-actor

我有一个系统,每个用户都有一个演员。用户很少发送消息,但是发送消息时,他们通常不仅发送消息,而且发送的消息很少。

目前,我有一张地图,用于存储persistenceId -> ActorRef。当我收到有关演员的新消息时,我会查看地图,如果有ActorRef,则会使用它。如果丢失,我将其创建并放入地图中。当然,我不想同时拥有2个相同持久性参与者的实例。另外,我不想为每个消息创建和销毁actor,因为恢复可能需要一些时间。

我觉得应该有一些更干净的“定位或创建”演员的方法。类似于actorSystem.getOrCreate(persistenceId, props)。我以为分片可能会帮助我解决这个问题,但是我找不到确切的例子。另外,我知道还有actorSelection,它有缺点:

  • 在太多的地方使用它,并且硬编码的路径很难 维持
  • 使用它发送太多消息,因为它具有性能 费用

因此,基本上的问题是,如果我的参与者persistenceId是userId,那么在一个服务中定位永久参与者的最佳方法是什么?如果我决定使用分片,则每个演员将为1个分片。这个可以吗?

1 个答案:

答案 0 :(得分:2)

演员分片几乎是您所需要的-您可以将其视为演员的分布式地图,而无需其他解决方案。分片将在幕后召集演员,而且您无需自己管理演员。

val sharding = ClusterSharding(system).start(
    typeName = CustomerActor.shardName,
    entityProps = CustomerActor.props,
    settings = ClusterShardingSettings(system),
    extractEntityId = CustomerActor.extractEntityId,
    extractShardId = CustomerActor.extractShardId)
}

其中extractEntityId是将消息路由到适当参与者的功能

val extractEntityId: ShardRegion.ExtractEntityId = {
  case gc: GetCustomer => (gc.customerId, gc)
}

最后一个例子:

case class GetCustomer(customerId: String)

sharding ! GetCustomer("customer-id")

更多详细信息,请点击https://doc.akka.io/docs/akka/2.5/cluster-sharding.html