Akka演员是否因为进行数据处理/上传而过度使用?

时间:2018-03-14 14:33:54

标签: scala akka future actor

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

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

  1. 打开与消息代理的套接字连接
  2. 查询外部REST服务一次
  3. 向另一个内部服务发出许多大而长的REST请求,对响应进行数学运算,并将结果发送出去。消息通过套接字连接发送,作为进度更新。
  4. 可伸缩性是这里的主要关注点,因为我们通常每分钟可以收到~10个小请求,但是在未知的时间会同时收到几个令人痛苦的巨大且长时间运行的请求。

    使用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处理上述未来下面的所有线程将允许它们全部并行运行。

    这绝对可以用Akka演员写的,但我不知道在这样做的过程中会有什么好处,如果有的话。将上述内容变成一个基于演员的流程,并且需要一大堆工作人员进行处理?是不是有点过分了?

1 个答案:

答案 0 :(得分:2)

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

所以期货(或者最好是诸如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等内容,你可以通过控制器传回未来。或者手动看看你的示例代码。