Akka actors 做数据是不是矫枉过正 crunching/uploading?

Are Akka actors overkill for doing data crunching/uploading?

我对 Scala 和 Akka 演员都很陌生。我现在真的只是在阅读它们的使用和实现。我的背景主要是 js 和 python 以及一点 C#。

我必须编写的一个新服务将接收 REST 请求,然后执行以下操作:

  1. 打开到消息代理的套接字连接
  2. 查询一次外部 REST 服务
  3. 向另一个内部服务发出许多又大又长的 REST 请求,对响应进行计算,然后将结果发送出去。消息作为进度更新通过套接字连接发送。

可扩展性是这里的主要关注点,因为我们通常每分钟可能会收到大约 10 个小请求,但在未知的时间会同时收到几个令人瞠目结舌的巨大且长 运行ning 请求。

使用 Scala Futures,非常基本的 实现将是这样的:

val smallResponse = smallHttpRequest(args)

smallResponse.onComplete match {
  case Success(result) => {
    result.data.grouped(10000).toList.forEach(subList => {
      val bigResponse = getBigSlowHttpRequest(subList)
      bigResponse.onSuccess {
        case crunchableStuff =>  crunchAndDeliver(crunchableStuff)
      }
    })
  }
  case Failure(error) => handleError(error)
}

我的理解是,在具有多个内核的机器上,让 JVM 处理上述 futures 下的所有线程将允许它们全部并行 运行。

这绝对可以使用 Akka actors 来编写,但我不知道这样做有什么好处(如果有的话)。将上面的内容变成一个基于参与者的过程,让一群工人占用 c运行ching 的大块是不是太过分了?

对于这样的操作,我不会靠近 Akka Actors —— 对于看起来非常基本的异步请求链来说,它太多了。 Actor 系统使您能够安全地处理 and/or 在 actor 中累积状态,同时您的任务可以轻松地建模为类型安全的无状态数据流。

因此 Futures(或者最好是 Twitter Future、cats.IO、fs2 Task、Monix 等许多惰性变体之一)可以轻松处理。

没有 IDE 手头,所以这里肯定有一个很大的错误!

val smallResponse = smallHttpRequest(args)

val result: Future[List[CrunchedData]] = smallResponse.map(result => {
        result.data
              .grouped(10000)
              .toList
              // List[X] => List[Future[X]]
              .map(subList => getBigSlowHttpRequest(subList))
              // List[Future[X]] => Future[List[X]] so flatmap
              .flatMap(listOfFutures => Future.sequence(listOfFutures))
         })

之后,如果使用 Finch、Http4s、Play、Akka Http 等,您可以通过控制器将 future 传回。或者手动查看您的示例代码。