我有一个系统,每个用户都有一个演员。用户很少发送消息,但是发送消息时,他们通常不仅发送消息,而且发送的消息很少。
目前,我有一张地图,用于存储persistenceId -> ActorRef
。当我收到有关演员的新消息时,我会查看地图,如果有ActorRef,则会使用它。如果丢失,我将其创建并放入地图中。当然,我不想同时拥有2个相同持久性参与者的实例。另外,我不想为每个消息创建和销毁actor,因为恢复可能需要一些时间。
我觉得应该有一些更干净的“定位或创建”演员的方法。类似于actorSystem.getOrCreate(persistenceId, props)
。我以为分片可能会帮助我解决这个问题,但是我找不到确切的例子。另外,我知道还有actorSelection
,它有缺点:
因此,基本上的问题是,如果我的参与者persistenceId是userId,那么在一个服务中定位永久参与者的最佳方法是什么?如果我决定使用分片,则每个演员将为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