4

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

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

我觉得应该有一些更简洁的方式来“定位或创造”一个演员。类似的东西actorSystem.getOrCreate(persistenceId, props)。我认为分片可能会帮助我,但我找不到一个确切的例子。另外,我知道有actorSelection,它有缺点:

  • 在太多地方使用它,硬编码的路径很难维护
  • 使用它来发送太多消息,因为它有性能成本

所以基本上问题是如果我的演员persistenceId是userId,那么在一项服务中定位持久演员的最佳方法是什么。如果我决定使用分片,那么每个演员 1 个分片。这个可以吗?

4

1 回答 1

3

Actor 分片几乎是您所需要的——您可以将其视为 Actor 的分布式地图,不需要额外的解决方案。分片负责在幕后召唤演员,无需您自己管理演员。

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

于 2018-11-07T15:50:35.213 回答