Найти актера по номеру персистентности - PullRequest
0 голосов
/ 07 ноября 2018

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

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

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

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

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

1 Ответ

0 голосов
/ 07 ноября 2018

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

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

...