为什么我应该使用异步/非阻塞框架构建API?

时间:2015-01-10 22:05:16

标签: api asynchronous playframework django-rest-framework

我一直在研究Play Framework作为帮助我构建简单API的可能候选者。然而,Django Rest Framework(DRF)似乎也是一个非常强大的竞争者。

据我所知,DRF并不像Play Framework那样宣传自己是异步(或非阻塞)框架,但我对这是否重要感兴趣。我一直在考虑的情况是通过Mandrill向用户发送电子邮件 - 我不希望我的API陷入困境,等待Mandrill API告诉它是否发送了电子邮件。

因此,我认为这个问题可以概括为:客户的观点是否有益于我使用异步/非阻塞框架(如Play over the DRF)构建API,或者我错过了这一点吗?

3 个答案:

答案 0 :(得分:15)

我是Django REST框架贡献者(和用户),因此我的观点偏向于此。

Django REST框架基于Django构建,Django是Web应用程序的同步框架。如果您已经在使用像Django这样的同步框架,那么拥有同步API 不是问题

现在,仅仅因为它是同步的,这并不意味着一次只能处理一个请求。大多数处理Django应用程序的Web服务器can handle multiple requests,其中一些主题甚至是somewhat asynchronously across multiple threads。通常这实际上不是问题,因为您的Web服务器通常可以处理许多并发请求,即使其中一些是阻塞的。当你有很长时间阻止通话时,你通常不希望在API中完成 - 你应该将其委托给后台工作人员,如CeleryResque

这不仅仅适用于Django,许多相同的原则适用于其他同步框架,如Rails和ASP.NET MVC。如果您有长时间运行的请求,通常应该将工作委托给其他进程而不是阻止请求。通常使用202响应代码for these cases

现在,这并不一定意味着异步框架是无用的。在Node.js等运行时,大多数框架handle requests asynchronously。在这些语言中使用同步框架没有意义,因此大多数库都是异步构建的。

您的选择非常依赖于您已经使用的工具。

答案 1 :(得分:3)

关于连接到您的应用程序的客户端,如果您的服务器使用异步/非阻塞(ANB)技术,则应该没有任何区别。但它可能会对您的应用程序可以处理的请求数量产生很大影响。

假设以下情形:检查FB / Google / etc访问令牌是否有效的请求,然后使用它来获取用户的社交个人资料,然后返回一些内容。

如果您在服务器中使用阻止http客户端,则在2个http请求中的每个请求期间,可以阻止服务该请求的线程大量时间无效。 如果您正在使用非阻塞的http客户端(如Play带来的那个),而在发出HTTP请求并且响应返回时,该线程可用于执行其他操作(例如:另一个请求的进程部分)。

请注意,要解决这个“问题”,您不需要ANB框架,只需要一个ANB http客户端。因此,您应该更多地了解应用程序中的操作类型,并检查所选框架将如何处理它们。例如:如果您的应用程序几乎包含DB CRUD操作且数据库驱动程序阻塞(如Java中的JDBC以及Django使用的那些),如果框架是异步的,那么它实际上并不重要,您将阻止大多数那个特定组件的时间。

在您的电子邮件示例中,Django + Celery可能与Play / Akka一样好。

答案 2 :(得分:1)

非异步框架通常会将长时间运行的任务传递给某些外部进程(例如,用于Rails开发的Resque / DelayedJob / sidekiq)

只想添加Mandrill API支持发送电子邮件的async参数。 以下是他们的文档所说的内容:

  

启用针对批量发送优化的后台发送模式。在异步模式下,消息/发送将立即返回"排队"为每个收件人。要在异步模式下发送时处理拒绝,请为拒绝'设置webhook。事件

因此,如果将async设置为true,您可以在执行API调用后立即处理,而无需等待发送所有电子邮件。

https://mandrillapp.com/api/docs/messages.JSON.html#method-send

(我以API的JSON版本为例)