Java 从actor调用的服务内长时间运行的进程

Java 从actor调用的服务内长时间运行的进程,java,scala,akka,actor,Java,Scala,Akka,Actor,我们在应用程序中使用Akka角色。参与者正在调用服务,在某些情况下,这些服务正在调用由第三方公开的RESTAPI。现在,第三方API需要很长时间才能响应。由于这一点,在高峰时间,系统通过put受到影响,因为线程在等待客户端API响应时被阻塞 有时在高峰时间,因为线程正在等待,消息只会在akka邮箱中等待很长时间,一旦阻塞的线程可用,消息就会被接收 我正在寻找一些解决方案,在这些解决方案中,我可以提高系统的吞吐量,并释放线程,以便actor消息可以开始处理 我正在考虑使用Future将RESTAP

我们在应用程序中使用Akka角色。参与者正在调用服务,在某些情况下,这些服务正在调用由第三方公开的RESTAPI。现在,第三方API需要很长时间才能响应。由于这一点,在高峰时间,系统通过put受到影响,因为线程在等待客户端API响应时被阻塞

有时在高峰时间,因为线程正在等待,消息只会在akka邮箱中等待很长时间,一旦阻塞的线程可用,消息就会被接收

我正在寻找一些解决方案,在这些解决方案中,我可以提高系统的吞吐量,并释放线程,以便actor消息可以开始处理

我正在考虑使用Future将RESTAPI调用从阻塞更改为非阻塞调用,并为此类RESTAPI调用创建一个专用的参与者。Actor将定期检查future是否已完成,然后发送一条完成消息,然后进程的其余部分可以继续。这样,阻塞线程的数量将减少,并可用于Actor消息处理

还希望为正在执行阻塞操作的参与者提供单独的执行上下文。现在我们有了全局执行上下文


需要对此进行进一步的输入。

首先,处理消息时不应阻塞是正确的,因此需要启动异步进程并立即从消息处理程序返回。然后,参与者可以在流程完成时发送另一条消息

您没有说明RESTAPI调用使用的是什么技术,但是像Akka HTTP这样的库在发出HTTP请求时将返回一个
Future
,因此您不需要在其周围添加自己的
Future
。例如:

def getStatus(): Future[Status] = 
  Http().singleRequest(HttpRequest(uri = "http://mysite/status")).flatMap {
    res =>
      Unmarshal(res).to[Status]
  }
如果出于某种原因正在使用同步库,请将调用包装在
Future(blocking{???})
中,以通知执行上下文它需要创建新线程。除非需要控制此操作的线程调度,否则不需要单独的执行上下文


您也不需要轮询
未来
,只需添加一个
onComplete
处理程序,该处理程序将内部消息发送回您的参与者,参与者随后处理API调用的结果。

这一点。但我想补充一点,如果你真的需要进行阻塞呼叫,你也可以考虑使用一个单独的调度器。在处理回调时必须小心:查看pipeTo模式。再次重申tim的观点,每当你使用“定期检查未来是否完成”这个词时,你都在做错事:未来有回调。