django:celery vs channels vs in-view

django: celery vs channels vs in-view

假设我的页面上有一个按钮,单击该按钮会向我的 api 端点发出 ajax 请求,然后从第 3 方站点获取数据。假设此任务大约需要 2-5 秒,超时时间为 5 秒。执行此操作的理想方法是什么:

  1. celery task.delay() 在 api 端点和 return 一个 url 每隔 x 间隔轮询一次结果。
  2. 只需在视图中执行即可

我看过的所有教程都建议使用 celery 方式,但对于处理最少的简单请求来说,这似乎很多 machinery/overhead。是否有一些普遍接受的阈值(完成前的秒数等),人们会在其中选择一个而不是另一个?

然后是 django-channels,它似乎是这个的理想选择。但是,乍一看,channel workers 和 celery tasks 之间的区别似乎很模糊。我可以用通道工作人员替换芹菜并将其用于上述任务吗?渠道是否也能处理我更长的 运行 任务?什么是 advantages/drawbacks 通道(使用芹菜或替代芹菜)?

最后,3 个 (celery/channels/in-view) 中的哪一个是给定示例场景的推荐方法?

我不是渠道方面的专家,但我们开始吧。

Channels 是 WSGI(新协议是 ASGI)之上的抽象,它允许您通过 "abstract" 通道进行通信。有时你会做 HTTP,有时是 websockets,有时是其他你几乎可以做任何通信模式的东西。

Celery 以类似的方式构造,它使用消息总线(有时是更复杂的代理机制,具体取决于您 运行 它的方式)将工作发送到可以发回可选结果的工作机器。

现在你选择哪个?

在视图中

除非您有专门为此目的设计的视图,否则我会避免这种情况。您将需要确保您的堆栈可以处理长期连接(例如,如果花费超过 30 秒,heroku 的路由器会抱怨)或者您将想要实现一些长轮询接口。

搭配芹菜

您需要完成所有设置才能在线使用。

拥有一个您想要其结果的任务将需要一个结果后端并传递任务 ID。

您需要实现一个视图,该视图可以查询 celery 以确定任务的完成、成功等位置。

例如

# kick of the task somewhere

def create_task(request, *args, **kwargs):
    task_id = some_task.delay(param)
    return Response({'task_id': task_id})

urls.py

url(r'^/tasks/<task_id>/$', name='task-progress')

views.py

def task_progress_view(request, task_id):
    # get fancier here, this is just an example
    return Response(some_task.AsyncResult(task_id).state)

这是一个非常简单的示例,但应该作为起点。

有频道

您需要设置一个总线,以与 celery 基本相同的方式将所需的视图放在一起,只是您仍然需要一段代码来使用一些重试、超时逻辑来获取数据等..

选择什么

Celery 将负责工作部分,您必须负责更新并通知您的客户。频道是处理后退和第四次的合理方式,但您可能不需要它。

我会考虑你还需要做什么。大多数应用程序在某些时候需要异步工作,因为业务逻辑经常要求它。如果你打算使用 websockets 之类的,但你不想将你的 django 应用程序分解成服务,我会硬着头皮做这两个。

如果你不需要超过一种通信协议,只需使用 celery 并进行视图。