Django与芹菜并发

问题描述 投票:1回答:2

我正在使用django框架并遇到一些性能问题。

我的views.py中有一个非常沉重的(大约需要2秒钟)。我们称之为heavy()

客户端使用ajax发送请求,该请求被路由到heavy(),并等待json响应。

坏的是,我认为heavy()不是并发的。如下图所示,如果有两个请求同时路由到heavy(),则必须等待另一个请求。换句话说,heavy()是串行的:在从当前请求返回之前它不能接受另一个请求。观察结果在我的本地机器上进行了测试和验证。

我试图在views.py concurrentasynchronous中创建函数。理想情况下,当有两个请求进入heavy()时,heavy()应该通过回调将作业抛给某个远程worker,然后返回。然后,heavy()可以处理另一个请求。任务完成后,回调可以将结果发送回客户端。逻辑如下所示:

但是,有一个问题:如果heavy()想要处理另一个请求,它必须返回;但如果它返回一些东西,django框架将向客户端发送(假)响应,客户端可能不会等待另一个响应。而且,虚假响应不包含正确的数据。我已经搜索了stackoverflow并找到了不太有用的提示。我想知道是否有人试过这个并且知道解决这个问题的好方法。

谢谢,

django multithreading asynchronous concurrency celery
2个回答
2
投票

首先要确保'uncurrency'实际上是由你的繁重任务造成的。如果你只使用一个django工人,那么无论它是什么,你一次只能处理一个请求。考虑让更多的工作者兼顾并发性,因为它也会影响短请求。

要在任务完成时返回一些信息,您至少可以通过以下两种方式完成:

  • 定期发送AJAX请求以获取任务的状态
  • 使用SSE或websocket订阅实际结果

它们都需要编写更多的JavaScript代码来处理它。第一个很容易实现,第二个可以使用uWSGI功能,如here所述。它可以以这种方式异步处理,独立于你的django工作者(django只会在芹菜中创建连接和启动任务,检查状态并将其发送到客户端将由gevent处理。


0
投票

跟进GwynBliedD的回答:

芹菜通常用于处理任务,它具有非常简单的django集成。 @ GwynBlieD的第一个建议通常是使用芹菜和芹菜结果后端实现的。

https://www.reddit.com/r/django/comments/1wx587/how_do_i_return_the_result_of_a_celery_task_to/

常见的工作流程使用芹菜是:

  1. 客户端重()
  2. heavy()异步排队heavy()任务
  3. heavy()将未来的任务ID返回给客户端(由于实际执行的工作很少,因此视图返回非常快)
  4. 客户端使用任务ID开始轮询状态端点
  5. 当任务完成时,将结果返回给客户端
© www.soinside.com 2019 - 2024. All rights reserved.