Акка: Очистка динамически созданных актеров необходима, когда они закончили?
Я реализовал систему Actor с использованием Akka и Java API UntypedActor. В нем один актер (тип A) запускает другие участники (тип B) динамически по требованию, используя getContext().actorOf(...);
. Те B-актеры будут делать некоторые вычисления, которые A на самом деле не волнует больше. Но мне интересно: нужно ли очищать тех актеров типа B, когда они закончили? Если да, то как?
- Когда участники B вызывают
getContext().stop(getSelf())
, когда они закончены?
- Когда участники B вызывают
getSelf().tell(Actors.poisonPill());
, когда они закончатся? [это то, что я сейчас использую].
- Ничего не делая?
- По...?
Документы не ясны по этому поводу, или я не обратил на это внимания. У меня есть некоторые базовые знания Scala, но источники Akka - это не совсем вещи начального уровня...
Ответы
Ответ 1
То, что вы описываете, - это одноцелевые актеры, созданные за "запрос" (определенные в контексте A), которые обрабатывают последовательность событий, а затем выполняются, правильно? Это абсолютно нормально, и вы правы закрыть их: если вы этого не сделаете, они будут накапливаться с течением времени, и вы столкнетесь с утечкой памяти. Лучший способ сделать это - это первая из возможностей, которые вы упомянули (самая прямая), но вторая тоже хорошо.
Немного фона: актеры регистрируются в их родителях, чтобы быть идентифицируемыми (например, необходимыми в удалении, но также и в других местах), и эта регистрация не позволяет им собирать мусор. OTOH, каждый родитель имеет право доступа к созданным им детям, поэтому автоматическое завершение (то есть Akka) не имеет смысла, вместо этого требуется явное закрытие кода пользователя.
Ответ 2
В дополнение к ответу Роланда Куна вместо создания нового актера для каждого запроса вы можете создать предопределенный набор участников, которые используют один и тот же диспетчер, или вы можете использовать маршрутизатор, который распространяет запросы в пул участников.
"Балансирующий пул маршрутизатора" , например, позволяет вам иметь фиксированный набор участников определенного типа совместно использовать один и тот же почтовый ящик:
akka.actor.deployment {
/parent/router9 {
router = balancing-pool
nr-of-instances = 5
}
}
Прочитайте документацию по dispatchers и routing для более подробной информации.
Ответ 3
Я профилировал (visualvm) одно из примеров кластерного приложения из документации AKKA, и я вижу уборку мусора для каждого участника запроса во время каждого GC. Невозможно полностью понять рекомендацию явно убить актера после использования. Моя актерская система и актеры управляются контейнером IOC SPRING, и я использую расширение SPRING для прямого актера-продюсера для создания актеров. Актер " агрегатор" получает мусор, собранный на каждом GC, я контролировал # экземпляров в визуальной VM.
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class StatsService extends AbstractActor {
private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
@Autowired
private ActorSystem actorSystem;
private ActorRef workerRouter;
@Override
public void preStart() throws Exception {
System.out.println("Creating Router" + this.getClass().getCanonicalName());
workerRouter = getContext().actorOf(SPRING_PRO.get(actorSystem)
.props("statsWorker").withRouter(new FromConfig()), "workerRouter");
super.preStart();
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(StatsJob.class, job -> !job.getText().isEmpty(), job -> {
final String[] words = job.getText().split(" ");
final ActorRef replyTo = sender();
final ActorRef aggregator = getContext().actorOf(SPRING_PRO.get(actorSystem)
.props("statsAggregator", words.length, replyTo));
for (final String word : words) {
workerRouter.tell(new ConsistentHashableEnvelope(word, word),
aggregator);
}
})
.build();
}
}
Ответ 4
Актеры по умолчанию не потребляют много памяти. Если приложение намерено использовать актер b позже, вы можете сохранить их в живых. Если нет, вы можете закрыть их через яд. До тех пор, пока ваши актеры не будут располагать ресурсами, оставив актера в порядке.