Найти актера по номеру персистентности

У меня есть система, в которой есть актер на пользователя. Пользователи отправляют сообщения редко, но когда они это делают, они отправляют обычно не одно, а несколько.

В настоящее время у меня есть карта, где я храню persistenceId -> ActorRef, Когда я получаю новое сообщение для актера, я смотрю на карту, если есть ActorRef, я использую его. Если это отсутствует, я создаю это и помещаю это в карту. Конечно, я не хочу иметь 2 экземпляра одного и того же актера персистентности одновременно. Кроме того, я не хочу создавать и уничтожать актера для каждого сообщения, так как восстановление может занять некоторое время.

Я чувствую, что должен быть какой-то более чистый способ "найти или создать" актера. Что-то вроде actorSystem.getOrCreate(persistenceId, props), Я думал, что осколок может помочь мне с этим, но я не мог найти точный пример этого. Кроме того, я знаю, что есть actorSelection, который имеет недостатки:

  • использовать его в слишком многих местах, с жестко закодированными путями, которые сложно поддерживать
  • использование его для отправки слишком большого количества сообщений, так как это снижает производительность

Таким образом, в основном вопрос заключается в том, каков наилучший способ размещения субъекта персистентности в одном сервисе, если для субъекта персистентности используется идентификатор пользователя. Если я решу использовать шардинг, то это будет 1 шард на актера. Это нормально?

1 ответ

Решение

Разделение актеров - это почти то, что вам нужно - вы можете думать об этом как о распределенной карте актеров, и нет необходимости в дополнительных решениях. Осколок заботится о вызове актера за кулисы, и вам не нужно управлять актерами самостоятельно.

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

Другие вопросы по тегам