Akka actors 做数据是不是矫枉过正 crunching/uploading?
Are Akka actors overkill for doing data crunching/uploading?
我对 Scala 和 Akka 演员都很陌生。我现在真的只是在阅读它们的使用和实现。我的背景主要是 js 和 python 以及一点 C#。
我必须编写的一个新服务将接收 REST 请求,然后执行以下操作:
- 打开到消息代理的套接字连接
- 查询一次外部 REST 服务
- 向另一个内部服务发出许多又大又长的 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 传回。或者手动查看您的示例代码。
我对 Scala 和 Akka 演员都很陌生。我现在真的只是在阅读它们的使用和实现。我的背景主要是 js 和 python 以及一点 C#。
我必须编写的一个新服务将接收 REST 请求,然后执行以下操作:
- 打开到消息代理的套接字连接
- 查询一次外部 REST 服务
- 向另一个内部服务发出许多又大又长的 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 传回。或者手动查看您的示例代码。