我目前正在研究一个广泛使用Akka和Akka Streams的项目。我应该共享Materializer实例还是在需要时始终创建一个新实例?
使用它时会遇到一个问题/问题:在所有使用流的地方,Materializer的最佳实践是什么?特别是当我在Actor中时,只能访问ActorSystem,我应该手动传递一个现有的Materializer实例,还是只在需要时创建一个实例?
我特别担心按需实例化Materializers时的资源使用情况和性能。
我目前正在研究一个广泛使用Akka和Akka Streams的项目。我应该共享Materializer实例还是在需要时始终创建一个新实例?
使用它时会遇到一个问题/问题:在所有使用流的地方,Materializer的最佳实践是什么?特别是当我在Actor中时,只能访问ActorSystem,我应该手动传递一个现有的Materializer实例,还是只在需要时创建一个实例?
我特别担心按需实例化Materializers时的资源使用情况和性能。
创建ActorMaterializer
s相当便宜,在大多数情况下,它们的合理扩散不应该成为问题。
如果你追从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")
输出这对我的笔记本电脑
制度创新:901毫秒
物化器创建:14 ms
然而,正如约翰在评论中指出的那样,重要的是要补充物化器的生命周期需要得到妥善管理,只要他们停止使用,就调用shutdown
以避免资源泄漏。
回顾一下,尽可能传递物化器是一个很好的选择。不过,如果这不方便,它的创造便宜,但要注意正确关闭它。
我认为生命周期和生命周期管理比性能更重要。如果你关闭一个实现器,它的所有正在运行的流都会突然终止,如果你在一个actor中创建一个实现器,并且当你停止这个actor时你不关闭它,那么你正在泄漏资源。 – johanandren
绝对同意这一点,无论如何,表现并不是与2种选择中的任何一种大规模倾斜。 'mat.shutdown()'应该总是包含在你的actor的'postStop'方法中。 –