Akka 2.x需要许多命令来引用ActorSystem
。因此,要创建一个角色MyActor
的实例,您可能会说:
val system = ActorSystem()
val myActor = system.actorOf(Props[MyActor])
由于经常需要ActorSystem
:许多代码示例省略了代码的创建,并假设读者知道system
变量的来源。
如果您的代码在不同的地方生成actor,您可以复制此代码,可能创建其他ActorSystem
实例,或者您可以尝试通过引用某些全局或传递来共享相同的ActorSystem
实例ActorSystem
周围。
Akka文档在“Actor Systems”标题下提供了general overview of systems of actors,并且有documentation of the ActorSystem
class。但这些都没有帮助解释为什么Akka的用户不能仅仅依靠Akka管理这个内幕。
每次共享同一个ActorSystem
对象或创建新对象会有什么影响?
这里有哪些最佳做法?一直绕过ActorSystem
看起来非常严厉。
一些示例为ActorSystem
提供了一个名称:ActorSystem("MySystem")
其他人只需拨打ActorSystem()
。这会有什么不同,如果你两次使用相同的名称怎么办?
akka-testkit
是否要求您与传递给ActorSystem
构造函数的TestKit
共享一个公共{{1}}?
答案 0 :(得分:49)
创建ActorSystem非常昂贵,因此您希望每次需要时都避免创建新的ActorSystem。你的演员也应该在同一个ActorSystem中运行,除非他们有充分的理由不这样做。 ActorSystem的名称也是其中运行的actor的路径的一部分。例如。如果您在名为MySystem
的系统中创建一个actor,它将具有类似akka://MySystem/user/$a
的路径。如果您在actor上下文中,则始终引用ActorSystem。在演员中,您可以拨打context.system
。我不知道akka-testkit的期望,但你可以看看akka测试。
总而言之,你应该总是使用相同的系统,除非有充分的理由不这样做。
答案 1 :(得分:4)
以下是一些可能有助于理解“为什么文档始终建议将一个ActorSystem用于一个逻辑应用程序”的材料:
ActorSystem中最重的部分是调度程序。每个ActorSystem至少有一个。调度程序是使演员运行的引擎。为了运行,它需要线程(通常来自线程池)。默认调度程序使用具有至少8个线程的fork-join线程池。
有共享设施,如守护者,事件流,调度程序等。其中一些是在用户空间,一些是内部的。所有这些都需要创建和启动。
在大多数情况下,一个具有一个线程池配置到核心数量的ActorSystem应该能够提供最佳结果。
这里的文档提到了逻辑应用程序,我更喜欢考虑阻塞或非阻塞应用程序。根据调度员的配置,一个ActorSystem用于一个配置。如果应用程序使用相同的逻辑,那么一个ActorSystem就足够了。
这是一个discussion,如果你有时间,你可以阅读它。他们讨论了很多,ActorSystem,本地或远程等。