我是否需要重复使用相同的Akka ActorSystem,或者每次需要时都可以创build一个?

Akka 2.x需要许多命令才能引用ActorSystem 。 所以,要创build一个演员MyActor的实例,你可能会说:

 val system = ActorSystem() val myActor = system.actorOf(Props[MyActor]) 

由于对ActorSystem的频繁需求:许多代码示例省略了代码的创build,并假定读者知道systemvariables来自哪里。

如果你的代码在不同的地方产生了actor,你可以复制这个代码,可能创build更多的ActorSystem实例,或者你可以通过引用一些全局或者通过传递ActorSystem来共享相同的ActorSystem实例。

Akka文档提供了“演员系统”标题下演员系统的总体概述 ,并且有ActorSystem类的文档 。 但是这些都没有帮助解释为什么阿卡用户不能仅仅靠阿卡来pipe理这个问题。

问题(S)

  • 每次共享相同的ActorSystem对象或创build一个新对象有什么意义?

  • 这里最好的做法是什么? ActorSystem似乎令人吃惊。

  • 一些例子给了ActorSystem一个名字: ActorSystem("MySystem")其他的只是调用ActorSystem() 。 这有什么不同,如果你使用同一个名字两次?

  • akka-testkit是否要求您将您传递给TestKit构造函数的一个共享TestKit

创build一个ActorSystem是非常昂贵的,所以你想避免每次需要时创build一个新的。 另外,你的演员应该运行在同一个ActorSystem中,除非有充分的理由不要。 ActorSystem的名称也是其中运行actor的path的一部分。 例如,如果你在一个名为MySystem的系统中创build一个actor,它将会有一个像akka://MySystem/user/$a这样的path。 如果您在演员上下文中,则始终有一个对ActorSystem的引用。 在一个Actor中你可以调用context.system 。 我不知道akka-testkit期望的是什么,但是你可以看看akkatesting。

所以总结起来,你应该总是使用相同的系统,除非有充分的理由不这样做。

下面是一些可能有助于理解“为什么文档总是build议为一个逻辑应用程序使用一个ActorSystem”的材料:

  1. ActorSystem最重的部分是调度器。 每个ActorSystem至less有一个。 调度员是使演员运行的引擎。 为了运行,它需要线程(通常来自线程池)。 默认分派器使用至less有8个线程的fork-join线程池。

  2. 有共享的设施,如监护人,事件stream,调度器等,其中一些在用户空间,一些在内部。 所有这些都需要创build和启动。

  3. 一个具有一个线程池的ActorSystemconfiguration为内核的数量,在大多数情况下应该给出最好的结果。

  4. 这里的文档提到了逻辑应用,我更愿意考虑阻塞或者非阻塞的应用。 根据调度员的configuration,一个ActorSystem用于一个configuration。 如果应用程序使用相同的逻辑,则一个ActorSystem应该足够了。

这是一个讨论 ,如果你有时间,你可以阅读。 他们讨论了很多,ActorSystem,本地或远程等。