我应该共享 Materializer 实例还是始终在需要时创建一个新实例?

Should I share the Materializer instance or always create a new one when needed?

我目前正在从事一个广泛使用 Akka 和 Akka Streams 的项目。

一个 question/problem 在使用它时不断出现:什么是在所有使用流的地方都需要的 Materializer 的最佳实践。特别是当我在一个 Actor 中时,我只能访问 ActorSystem,我应该手动传入一个现有的 Materializer 实例还是只在需要时创建一个?

我特别担心按需实例化 Materializers 时的资源使用和性能问题。

ActorMaterializer 的创建成本相当低,并且在大多数情况下它们的合理扩散应该不是问题。

如果您追踪从 ActorMaterializer.apply 开始的调用链(参见 source code),您会发现 ActorMaterializer(或更好,ActorMaterializerImpl)没有执行创建时任何重要的东西。

为了让您了解它与 ActorSystem 创作的比较,请考虑以下代码

  val sysStart = System.nanoTime()
  val actorSystem = ActorSystem("mySystem")
  val sysDuration = FiniteDuration(System.nanoTime() - sysStart, TimeUnit.NANOSECONDS)
  println(s"System creation: ${sysDuration.toMillis} ms")

  val matStart = System.nanoTime()
  val materializer = ActorMaterializer()(actorSystem)
  val matDuration = FiniteDuration(System.nanoTime() - matStart, TimeUnit.NANOSECONDS)
  println(s"Materializer creation: ${matDuration.toMillis} ms")

在我的笔记本电脑上输出这个

System creation: 901 ms

Materializer creation: 14 ms

但是,正如 Johan 在评论中指出的那样,重要的是要补充一点,需要正确管理物化器的生命周期,在它们不再有用时调用 shutdown,以避免资源泄漏。

总而言之,尽可能传递实体化器是一个不错的选择。每当这不方便时,它的创建很便宜,但要注意正确关闭它。