Django REST Framework 发出异步请求以响应

Posted

技术标签:

【中文标题】Django REST Framework 发出异步请求以响应【英文标题】:Django REST Framework make asynchronous request to respond 【发布时间】:2015-12-17 08:22:58 【问题描述】:

我使用 Django Rest Framework 实现了一个 Django REST API。

对于这个 API,我必须调用 3 个 http Web 服务,并合并数据结果,例如我的 API 的响应。

所以,我有:

- Request WS 1
- Request WS 2
- Request WS 3
--> RESULT = Merge Results 1, 2, 3
----> Response: RESULT

是否可以将 Request WS 1、2,3 作为异步请求?

这是个好主意吗?

【问题讨论】:

【参考方案1】:

使用线程来执行此操作不是一个好主意,线程增加了更多复杂性并且可能难以调试。 在这种情况下,您可以使用任务调度程序(Celery、Django-RQ 等)。您必须根据您的系统选择一种。芹菜是众所周知的,但对你的系统来说可能太多了。

我建议使用 HTTP 状态和一些基本负载来解决此问题。 这个想法是获取请求,将“获取第三方站点任务”发送到任务调度程序并返回状态为 202 的“轮询 URL”。 “轮询 URL”是指 API 端点,用户可以在其中检查任务的状态。 HTTP 状态 202 告诉用户请求已被接受但处理尚未完成(其异步)。

然后 API 的被调用者可以每 X 次轮询“轮询 URL”,以获取任务的结果。 示例:

def api_process_request(request):
    data = process_data(request)
    polling_url = send_task_to_scheduler(data)
    return JsonResponse('url': polling_url, status=202)

def api_polling_url(request, task_id):
    done, result = task_scheduler_get_result(task_id)
    return JsonResponse('result': result, 'status': done, status=200)

希望对你有帮助! 祝你好运:)

【讨论】:

我喜欢 celery,但是如何使用 celery 或类似的东西,像这样比简单地使用线程更容易和更简单?有人可能会争辩说,为这样一个简单的用例使用多进程并启动异步分布式任务队列“增加了更多复杂性并且可能难以调试”。 @Sean,当然没问题。如果您在每个请求上生成一个线程,您可能会通过消耗您的资源来结束对您自己的应用程序的 DOS 攻击。通常,Web 服务器会启动几个“worker”,它们将负责运行 Django 并监听请求。如果您在运行 Django 堆栈的 worker(您的视图或其他 django 组件)内部生成线程,线程将继承来自 Django 的所有东西(它们共享内存空间),大多数时候这不是你想要的。 @Sean,我看到在请求-响应周期内进行线程处理的其他缺点是您最终会强制更多的“上下文切换”到内核,因为 Python 的线程被映射到系统线程,然后内核必须安排它们,它们也很昂贵。同样的想法适用于进程,不同之处在于您调用 fork() 系统调用,它将在全新的 Python 解释器中运行您的代码。谢谢! @Martin 很好的答案!我并没有考虑使用多个工人时事情会变得多么疯狂(我应该这样做,因为这是最常见的模式)。我现在和你在一起 - celery ftw :)

以上是关于Django REST Framework 发出异步请求以响应的主要内容,如果未能解决你的问题,请参考以下文章

使用 Django Rest Framework 返回当前用户

无法让 CORS 与内容类型一起使用 - Django Rest Framework

Axios受到使用Django REST Framework的CORS策略的阻止

如何使用 Axios 将 CSRF Coo​​kie 从 React 发送到 Django Rest Framework

如何覆盖与响应 django rest framework 序列化程序一起返回的返回序列化程序对象

Django Rest Framework在编辑用户时返回403 Forbidden,但在未以任何用户身份登录时工作