首页 > 解决方案 > 为什么在 Akka Streams 中添加异步边界会消耗大量 CPU?

问题描述

我发现我的 Akka Streams 程序有意外的 CPU 使用率。

这是一个简单的例子:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}

implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()

Source.repeat(Unit)
  .to(Sink.ignore)
  .run()

上面的代码片段将让 source 和 sink 在同一个 actor 中运行。

它在我的笔记本电脑上使用了大约 105% 的 CPU 使用率。按预期工作。

在我添加了一个异步边界之后:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}

implicit val system: ActorSystem = ActorSystem.create("QuickStart")
implicit val materializer: ActorMaterializer = ActorMaterializer()

Source.repeat(Unit)
  .async // <------ async boundary here
  .to(Sink.ignore)
  .run()

这段代码现在将在我的 4c8t 笔记本电脑上使用大约 600% 的 CPU 使用率。

我期望通过添加一个异步边界,该流将在 2 个单独的参与者中运行,并且将花费 200% 以上的 CPU。但它的成本远远超过 200%。

什么可能导致异步边界使用那么多 CPU?

标签: scalaakkaakka-stream

解决方案


默认akka.actor.default-dispatcher参数是 Java 的ForkJoinPool. 它是通过调用来初始化的ThreadPoolConfig.scaledPoolSize。因此,它默认为大小的起始池(处理器数 * 3)和 max = parallelism-max(64)。


推荐阅读