gpt4 book ai didi

akka - 为什么我的请求由spray-http 中的单个线程处理?

转载 作者:行者123 更新时间:2023-12-04 22:59:59 27 4
gpt4 key购买 nike

我使用spray-can、spray-http 1.3.2 和akka 2.3.6 设置了一个http 服务器。
我的 application.conf 没有任何 akka(或 Spray)条目。我的 Actor 代码:

class TestActor extends HttpServiceActor with ActorLogging with PlayJsonSupport {
val route = get {
path("clientapi"/"orders") {
complete {{
log.info("handling request")
System.err.println("sleeping "+Thread.currentThread().getName)
Thread.sleep(1000)
System.err.println("woke up "+Thread.currentThread().getName)
Seq[Int]()
}}
}
}

override def receive: Receive = runRoute(route)
}

开始是这样的:
val restService = system.actorOf(Props(classOf[TestActor]), "rest-clientapi")

IO(Http) ! Http.Bind(restService, serviceHost, servicePort)

当我发送 10 个并发请求时,它们都被 Spray 立即接受并转发给不同的调度器 actor(根据我已从 applicaiton.conf 中删除的 akka 日志配置,以免影响结果),但所有请求都由同一线程处理,它在 sleep ,只有在醒来后才会接收下一个请求。

我应该在配置中添加/更改什么?从我在 reference.conf 中看到的默认执行器是一个 fork-join-executor,所以我希望所有的请求都开箱即用地并行执行。

最佳答案

从你的代码我看到只有一个 TestActor处理所有请求,因为您只使用 system.actorOf 创建了一个请求.你知道,actorOf不会为每个请求创建新参与者 - 不仅如此,您还有 val那里,所以只有一个 Actor 。这个 actor 一个接一个地按顺序处理请求,并且您的路由在这个 actor 内处理。调度员没有理由选择另一个线程,而每次只有一个线程只被一个 Actor 使用,所以你在日志中只有一个线程(但不能保证) - 我假设它是第一个池中的线程。

Fork-join executor 在这里什么都不做,除了提供第一个并且始终相同的空闲线程,因为没有更多的 actor 需要与当前线程并行的线程。因此,它一次只接收一项任务。即使使用“工作窃取” - 它也不起作用,直到您有一些阻塞(并标记为具有托管块)的线程来“窃取”资源。 Thread.sleep(1000)本身不会自动标记线程 - 你应该用 scala.concurrent.blocking 将它包围起来使用“工作窃取”。无论如何,它仍然只有一个线程,而您只有一个 Actor 。

如果您需要有多个参与者来处理请求 - 只需传递一些 akka router actor (它与喷雾路由器没有任何共同之处):

val restService = context.actorOf(RoundRobinPool(5).props(Props[TestActor]), "router")  

这将创建一个包含 5 个参与者的池(不是线程池)来满足您的请求。

关于akka - 为什么我的请求由spray-http 中的单个线程处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28884268/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com