11

我来自 Java,在那里我将Runnables 提交给ExecutorService由线程池支持的线程池。在 Java 中如何设置线程池大小的限制非常清楚。

我对使用 Scala 演员很感兴趣,但我不清楚如何限制并发性。

假设说,我正在创建一个接受“工作”的 Web 服务。作业随POST请求一起提交,我希望我的服务将作业排入队列然后立即返回202 Accepted——即作业是异步处理的。

如果我使用演员来处理队列中的作业,我如何限制同时处理的作业数量?

我可以想出几种不同的方法来解决这个问题;我想知道是否有社区最佳实践,或者至少有一些在 Scala 世界中有些标准的明确确立的方法。

我想到的一种方法是让一个协调器参与者来管理作业队列和作业处理参与者;我想它可以使用一个简单的 int 字段来跟踪当前正在处理的作业数量。但是,我确信这种方法会有一些问题,例如确保跟踪错误发生的时间以减少数字。这就是为什么我想知道 Scala 是否已经为此提供了一种更简单或更封装的方法。

顺便说一句,我不久前试图问这个问题,但我问得很糟糕。

谢谢!

4

3 回答 3

7

I'd really encourage you to have a look at Akka, an alternative Actor implementation for Scala.

http://www.akkasource.org

Akka already has a JAX-RS[1] integration and you could use that in concert with a LoadBalancer[2] to throttle how many actions can be done in parallell:

[1] http://doc.akkasource.org/rest [2] http://github.com/jboner/akka/blob/master/akka-patterns/src/main/scala/Patterns.scala

于 2010-02-22T20:24:37.913 回答
5

您可以覆盖系统属性actors.maxPoolSizeactors.corePoolSize限制参与者线程池的大小,然后在池中抛出您的参与者可以处理的尽可能多的作业。为什么你认为你需要限制你的反应?

于 2010-02-22T18:23:40.863 回答
3

你在这里真的有两个问题。

首先是控制参与者使用的线程池。这可以通过设置系统属性actors.maxPoolSize 来完成。

第二个是已提交到池中的任务数量的失控增长。您可能关心也可能不关心这个问题,但是完全有可能触发故障条件,例如内存不足错误,并且在某些情况下,通过太快生成太多任务可能会导致更微妙的问题。

每个工作线程维护一个任务出队。出队被实现为一个数组,工作线程将动态扩大到某个最大大小。在 2.7.x 中,队列本身会变得非常大,我已经看到当与大量并发线程结合使用时会触发内存不足错误。最大出队大小小于 2.8。出队也可以填满。

解决此问题需要您控制生成的任务数量,这可能意味着您已经概述了某种协调器。当启动某种数据处理管道的参与者比管道中稍后的参与者快得多时,我遇到了这个问题。为了控制这个过程,我通常让链中较晚的参与者在每 X 条消息后 ping 回链中较早的参与者,并让链中较早的参与者在 X 条消息后停止并等待 ping 返回。您也可以使用更集中的协调器来完成。

于 2010-02-23T01:34:26.873 回答