22

当涉及在 akka http 上创建具有 60 多个 API 的 REST Web 服务时。我如何选择应该使用 akka 流还是使用 akka 演员?在他的帖子中,Jos 展示了在 akka http 上创建 API 的两种方法,但他没有展示我何时应该选择其中一种。

4

2 回答 2

24

这是一个困难的问题。显然,这两种方法都有效。所以在某种程度上,这是一个品味/熟悉的问题。所以接下来的一切都只是我个人的看法。

如果可能,我更喜欢使用 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 实现它。否则,请使用参与者或混合解决方案来实施。

于 2015-11-05T08:17:34.763 回答
11

不要忘记期货!

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

有一篇很棒的博客文章描述了 Future 何时是比 Actor 更好的选择。此外,Streams 提供的背压带来了相当大的开销

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

路线

Route在类型定义中固有地容纳 Futures :

type Route = (RequestContext) ⇒ Future[RouteResult]

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

val requestHandler : RequestContext => HttpResponse = ???

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

onComplete 指令

onComplete指令允许您在您的路线中“解开”未来:

val route = 
  get {

    val future : Future[HttpResponse] = ???

    onComplete(future) {
      case Success(httpResponse) => complete(httpResponse)
      case Failure(exception)    => complete(InternalServerError -> exception.toString)
    }
  } 
于 2015-11-05T12:50:44.333 回答