按持久化ID查找演员

4
我有一个系统,每个用户都有一个actor。用户很少发送消息,但当他们发送时,通常不只是一个,而是多个。
目前,我有一个映射,其中存储了ActorRef>。当我接收到一个新的消息时,我查找映射表,如果存在ActorRef,则使用它。如果不存在,则创建它并将其放入映射表中。当然,我不希望同时拥有相同持久性actor的两个实例。此外,我不想为每个消息创建和销毁actor,因为恢复可能需要一些时间。
我感觉应该有一种更干净的方式来“查找或创建”actor。类似actorSystem.getOrCreate(persistenceId, props)这样的东西。我认为分片可能会帮助我解决这个问题,但我找不到确切的示例。此外,我知道有actorSelection,它有一些缺点:
  • 在太多地方使用它,硬编码路径很棘手
  • 使用它发送太多消息会有性能成本
所以基本上问题是,在一个服务中定位持久性actor的最佳方法是什么,如果我actor persistenceId是userId。如果我决定使用分片,则每个actor将有1个分片。这可以吗?
1个回答

3

Actor sharding就是你需要的——你可以将其看作具有分布式映射功能的actor,无需使用其他解决方案。sharding会在幕后管理actor并召唤它们,你不需要自己管理actor。

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

其中extractEntityId是一个函数,用于将消息路由到适当的actor。

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

这个链接涉及到it技术中的集群分片。

如果我有一个构造函数CustomerActor(customerId: CustomerId),其中customerId仅用于创建persistenceId,那该怎么办?或者这是一种不正确的方法,我应该使用actor.path作为persistence id? - psisoyev
在文档中找到答案 - // self.path.name 是实体标识符(utf-8 URL编码) - psisoyev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接