在Scala中使用参与者时如何限制并发性?

在Scala中使用参与者时如何限制并发性?,scala,concurrency,actor,Scala,Concurrency,Actor,我来自Java,在那里我将Runnables提交给一个ExecutorService,该服务由一个线程池支持。在Java中,如何设置线程池大小的限制是非常清楚的 我对使用Scala参与者感兴趣,但不清楚如何限制并发性 假设我正在创建一个接受“工作”的web服务。作业随POST请求一起提交,我希望我的服务将作业排队,然后立即返回202 Accepted——即作业是异步处理的 如果使用参与者处理队列中的作业,如何限制同时处理的作业数量 我可以想出几种不同的方法来解决这个问题;我想知道是否有一个社区最

我来自Java,在那里我将
Runnable
s提交给一个
ExecutorService
,该服务由一个线程池支持。在Java中,如何设置线程池大小的限制是非常清楚的

我对使用Scala参与者感兴趣,但不清楚如何限制并发性

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

如果使用参与者处理队列中的作业,如何限制同时处理的作业数量

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

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

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


谢谢

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

我真的鼓励你看看Akka,它是Scala的另一种演员实现

Akka已经有了一个JAX-RS[1]集成,您可以将其与负载平衡器[2]配合使用,以限制并行操作的数量:

[1]
[2]

这里确实有两个问题

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

第二个问题是提交到池中的任务数量急剧增长。您可能关心也可能不关心这一点,但是完全有可能触发故障条件,例如内存不足错误,在某些情况下,由于生成太多任务太快,可能会引发更微妙的问题

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


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

非常有用,谢谢!我不确定我是否会使用“节流”一词,但无论如何,有时需要限制同时进行的“过程”的数量,因为它们所做的工作是资源密集型的。这种方法可能不会产生预期的结果。它将允许作业排队,直到JVM内存耗尽。限制参与者可以使用的线程数量只会限制实际并发执行的作业数量。我已经产生了OOM错误,因为生成工作的速度比演员以前快,所以你必须小心。我认为这种方法的一个缺点是它是全球性的。有时我需要运行不同类型的进程,这些进程具有不同的资源利用率级别——通过Java线程池,我可以轻松地使用具有不同设置的不同池。使用
actors.maxPoolSize
,我只能对所有actor使用一个数字,因为它们都由同一个线程池供电,对吗?有些链接已失效。