我是不是需要重复使用相同的 Akka ActorSystem 或者我可以在每次需要时创建一个?

Posted

技术标签:

【中文标题】我是不是需要重复使用相同的 Akka ActorSystem 或者我可以在每次需要时创建一个?【英文标题】:Do I need to re-use the same Akka ActorSystem or can I just create one every time I need one?我是否需要重复使用相同的 Akka ActorSystem 或者我可以在每次需要时创建一个? 【发布时间】:2012-05-10 21:53:43 【问题描述】:

Akka 2.x 需要许多命令来引用 ActorSystem。因此,要创建演员 MyActor 的实例,您可能会说:

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

由于经常需要ActorSystem:许多代码示例省略了代码的创建,并假设读者知道system 变量的来源。

如果您的代码在不同的地方产生演员,您可以复制此代码,可能会创建额外的 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 是否要求您与传递给TestKit 构造函数的ActorSystem 共享一个公共ActorSystem

【问题讨论】:

听起来你在 ActorSystem 之外编程太多了。您能否分享需要在 ActorSystem 周围传递的具体代码片段?仅供参考,在演员中,您可以通过以下方式获取其系统: context.system 另外,drexin 是对的,ActorSystem 非常重量级,因此每个逻辑应用程序只创建一个。 另外,你真的不应该创建很多***参与者:“system.actorOf”,因为这会创建一个非常无意义的错误内核,并且不会随着***参与者的创建需要阻止而扩展创建实例。 解释为什么 Akka 不能“在幕后”做到这一点是,在那里所做的任何事情都必须是全局的,我们发现这根本无法扩展(想象几个框架使用 Akka 用于不同的目的,如已经是这样了)。所以我们付出了巨大的努力来移除所有的全局状态。与此相比,您的“不便”很小;-)(您可以在应用程序中创建自己的单例,没有什么可以阻止您) 【参考方案1】:

创建一个 ActorSystem 非常昂贵,因此您希望避免在每次需要时都创建一个新的。此外,您的演员应该在同一个 ActorSystem 中运行,除非他们有充分的理由不这样做。 ActorSystem 的名称也是在其中运行的演员的路径的一部分。例如。如果您在名为MySystem 的系统中创建一个actor,它将有一个类似akka://MySystem/user/$a 的路径。如果你在一个演员上下文中,你总是有一个对 ActorSystem 的引用。在 Actor 中,您可以调用 context.system。我不知道 akka-testkit 期望什么,但你可以看看 akka 测试。

总而言之,您应该始终使用相同的系统,除非有充分的理由不这样做。

【讨论】:

“你应该始终使用同一个系统” 在某些用例中,拥有多个系统是有意义的。 比如什么?多租户应用程序呢? 例如,框架可以使用不应从用户代码访问的内部参与者系统。 Play 这样做是为了处理请求。 有人有一些数据来比较不同情况下的表现吗?【参考方案2】:

这里有一些材料可能有助于理解“为什么文档总是建议将一个 ActorSystem 用于一个逻辑应用程序”:

    ActorSystem 最重的部分是调度程序。每个 ActorSystem 至少有一个。调度程序是使参与者运行的引擎。为了使其运行,它需要线程(通常从线程池中获取)。默认调度程序使用至少有 8 个线程的 fork-join 线程池。

    有一些共享设施,比如监护人演员、事件流、调度程序等。其中一些在用户空间,一些在内部。所有这些都需要创建和启动。

    一个带有一个线程池的 ActorSystem 配置为核心数量在大多数情况下应该会产生最佳结果。

    这里文档提到了逻辑应用程序,我更喜欢考虑阻塞或非阻塞应用程序。根据 dispatcher 的配置,一个 ActorSystem 对应一个配置。如果应用程序用于相同的逻辑,则一个 ActorSystem 就足够了。

这里有一个discussion,有时间可以看一下。他们讨论了很多,ActorSystem,本地或远程等。

【讨论】:

以上是关于我是不是需要重复使用相同的 Akka ActorSystem 或者我可以在每次需要时创建一个?的主要内容,如果未能解决你的问题,请参考以下文章

(转)Akka学习笔记

Scala Actors迁移指南

Akka 框架支持查找重复消息

在 Play Framework 2.4 中为 Scala 实现 Akka

Scala框架Akka学习

二 Akka学习 - actor介绍