akka http:Akka 流与演员建立休息服务
Posted
技术标签:
【中文标题】akka http:Akka 流与演员建立休息服务【英文标题】:akka http: Akka streams vs actors to build a rest service 【发布时间】:2016-02-05 20:53:06 【问题描述】:当谈到在 akka http 上创建具有 60 多个 API 的 REST Web 服务时。我如何选择应该使用 akka 流还是使用 akka 演员? 在他的post 中,Jos 展示了两种在 akka http 上创建 API 的方法,但他没有说明我应该何时选择其中一种。
【问题讨论】:
【参考方案1】:这是一个难题。显然,这两种方法都有效。所以在某种程度上,这是一个品味/熟悉的问题。所以接下来的一切都只是我个人的看法。
如果可能,我更喜欢使用 akka-stream,因为它具有更高级别的性质和类型安全性。但这是否是一种可行的方法在很大程度上取决于 REST API 的任务。
Akka 流
如果您的 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 实现它。否则,请使用演员或混合解决方案实施。
【讨论】:
感谢 Rüdiger 的明确回答。我不喜欢将两者混合在一起,因为要获得背压,您需要依赖发布者/订阅者模型来处理您的演员。如果您想将请求向下发送到参与者层次结构,这会迫使您严重依赖ask
模式而不是 tell
。考虑到新参与者的微不足道的成本,每个请求的参与者模式很有价值。我还看到流作为底层子服务的聚合器工作得非常好,可以轻松地对子 API 进行分组。当您为 # 请求应该最少的移动设备进行开发时,这一点尤为重要。你怎么看?
说实话,我尽量使用akka-stream,只有在有特殊部署或其他需求时才使用原始actors。我认为很多用例都很好地映射到 akka-stream。
太棒了!顺便说一句,您能否提供一个简单的用例:“如果您的 API 允许查询和更新集群上的多个持久性参与者,那么参与者可能会更可取。”【参考方案2】:
别忘了期货!
我要对 Rudiger Klaehn 的好答案做的一个附录是还要考虑 Future
的用例。 Futures 的可组合性和 ExecutionContext
的资源管理使 Futures 成为许多(如果不是大多数)情况的理想选择。
有一个很好的blog post 描述了Futures 何时是比Actors 更好的选择。此外,Streams 提供的背压带来了相当大的overhead。
仅仅因为您使用 akka-http 陷入困境并不意味着您的请求处理程序中的所有并发都必须限制在 Actor 或 Streams 中。
路线
Route
在type definition 中固有地容纳期货:
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)
【讨论】:
以上是关于akka http:Akka 流与演员建立休息服务的主要内容,如果未能解决你的问题,请参考以下文章