akka http:Akka streams vs actors 构建休息服务

akka http: Akka streams vs actors to build a rest service

在 akka http 上使用 60+ API 创建 REST Web 服务。我如何选择我应该使用 akka 流还是 akka 演员? 在他的 post 中,Jos 展示了两种在 akka http 上创建 API 的方法,但他没有展示我何时应该 select 一个优于另一个。

这是一道难题。显然,这两种方法都有效。所以在某种程度上是taste/familiarity的事情。所以接下来的一切都只是我个人的看法。

如果可能,我更喜欢使用 akka-stream,因为它具有更高级别的特性和类型安全性。但这是否可行在很大程度上取决于 REST 的任务 API.

阿卡流

如果您的 REST API 是一项服务,例如根据外部数据(例如货币汇率API)回答问题,最好使用akka-stream实现。

另一个 akka-stream 更可取的例子是某种数据库前端,其中 REST API 的任务是解析查询参数,将它们转换为数据库查询,执行查询并转换结果根据用户请求的内容类型。在这两种情况下,数据流都可以轻松映射到 akka-stream 原语。

演员

如果您的 API 允许查询和更新集群上的多个持久性参与者,那么使用参与者可能是更可取的一个例子。在这种情况下,纯基于 actor 的解决方案或混合解决方案(使用 akka-stream 解析查询参数和转换结果,其余使用 actor 完成)可能更可取。

如果您有一个 REST API 用于长 运行 请求(例如 websockets),并且想要部署处理管道,那么基于参与者的解决方案可能更可取的另一个示例集群上的 REST API 本身。我认为目前使用 akka-stream 根本 不可能有这样的事情。

总结

总结一下:查看每个 API 的数据流,看看它是否清晰地映射到 akka-stream 提供的原语。如果是这种情况,请使用 akka-stream 实现它。否则,使用参与者或混合解决方案实施。

不要忘记期货!

我要对 Rudiger Klaehn 的好回答做的一个补充是还要考虑 Future 的用例。 Futures 的可组合性和 ExecutionContext 的资源管理使 Futures 成为许多(如果不是大多数)情况的理想选择。

有个优秀的blog post describing when Futures are a better choice than Actors. Further, the back-pressure provided by Streams comes with some pretty hefty .

仅仅因为您使用 akka-http 陷入困境并不意味着您的请求处理程序中的所有并发性都必须限制在 Actors 或 Streams 中。

路线

Route 本质上在 type definition:

中容纳期货
type Route = (RequestContext) ⇒ Future[RouteResult]

因此,您可以仅使用函数和 Futures,而不使用指令,将 Future 直接烘焙到您的 Route 中:

val requestHandler : RequestContext => HttpResponse = ???

val route : Route = 
  (requestContext) => Future(requestHandler(requestContext)) map RouteResult.Complete

完成指令

onComplete 指令允许您 "unwrap" 在您的路线中创建未来:

val route = 
  get {

    val future : Future[HttpResponse] = ???

    onComplete(future) {
      case Success(httpResponse) => complete(httpResponse)
      case Failure(exception)    => complete(InternalServerError -> exception.toString)
    }
  }