不确定这个问题是否适合此问题
我有一个akka-http应用程序,它充当了一些繁重计算的前沿。它处理的请求在处理它们的时间上有所不同。有些在一秒钟内完成,有些则需要更多。计算完全是异步的,任何时候都没有Await
,我用Future完成请求,即:
val spotsJsonF: Future[String] = spotsF.map(spots => DebugFormatter.produceJson(text, spots._1, spots._2, env))
complete(spotsJsonF.map { t => HttpEntity(ContentTypes.`application/json`, t) })
我的要求/假设:
为此,我为繁重的计算提供了一个单独的执行上下文(即Scala的默认ExecutionContext.global
),即它在不同的线程池上生成并修改Future
s到一个由Akka http调度员使用的。我以为这会停止计算和坐下来#34;在Akka的线程上,所以它可以接受更多的连接。目前,它是Akka的默认调度程序(我的reference.conf
为空):
"default-dispatcher": {
"attempt-teamwork": "on",
"default-executor": {
"fallback": "fork-join-executor"
},
"executor": "default-executor",
"fork-join-executor": {
"parallelism-factor": 3,
"parallelism-max": 64,
"parallelism-min": 8,
"task-peeking-mode": "FIFO"
},
"mailbox-requirement": "",
"shutdown-timeout": "1s",
"thread-pool-executor": {
"allow-core-timeout": "on",
"core-pool-size-factor": 3,
"core-pool-size-max": 64,
"core-pool-size-min": 8,
"fixed-pool-size": "off",
"keep-alive-time": "60s",
"max-pool-size-factor": 3,
"max-pool-size-max": 64,
"max-pool-size-min": 8,
"task-queue-size": -1,
"task-queue-type": "linked"
},
"throughput": 5,
"throughput-deadline-time": "0ms",
"type": "Dispatcher"
},
但是,由于超时,Akka取消请求后,长时间运行的计算会持续执行。使用有限数量的内核,这意味着即使不再需要启动此重载的计算,拒绝请求的数量也会增加。
显然,我不知道如何正确管理此应用程序中的线程。
满足我要求的最佳方法是什么?几个线程池 - 好/坏主意?我需要明确取消吗?可能正在使用Scala的vanilla目前还不是最好的选择吗?
答案 0 :(得分:2)
对我而言,这听起来并不是关于管理线程,将繁重的工作分离给您已经完成的单独调度员,而是关于管理实际处理。
为了能够在工作中停止长时间运行的过程,您可能需要将其拆分为较小的块,以便在不再需要时可以在中途中止它。
与actor有一个共同的模式是让一个处理参与者将结果“存储到目前为止”或者将其作为消息发送给自己,这样它就可以对两者之间的“停止工作”消息作出反应,或者可能检查它是否存在已经处理了这么长的时间,它应该中止。触发工作负载的消息可以包含例如允许“客户端”指定它的超时值。
(这与在手动线程和阻止应用程序中正确处理InterruptedException
和Thread.isInterrupted
基本相同)