假设我的页面上有一个按钮,当点击它时会向我的api端点发出ajax请求,然后从第三方站点获取数据。假设此任务大约需要2-5秒,超时时间为5秒。这样做的理想方式是什么:
我见过的所有教程都提出了芹菜的方式,但对于一个简单的处理来说,这似乎是很多机器/开销。是否存在一些普遍接受的阈值(直到完成的秒数等),其中一个会选择一个而不是另一个?
然后有django-channels,这似乎是理想的。但是,乍一看,渠道工人和芹菜任务之间的区别似乎很模糊。我可以用渠道工人替换芹菜,并将其用于上述任务吗?渠道还能处理我长期运行的任务吗?渠道的优点/缺点是什么(芹菜或替代芹菜)?
最后,3个(celery / channels / in-view)中的哪一个将是给出的示例场景的推荐方法?
答案 0 :(得分:1)
我不是渠道专家,但我们走了。
频道是WSGI之上的抽象(新协议是ASGI),它允许您通过"抽象"通道。有时你会做HTTP,有时是websockets,有时候其他东西你可以做任何通信模式。
Celery以类似的方式构建,它使用消息总线(有时是一种更复杂的代理机制,具体取决于您运行它的方式)将工作发送到可以发回可选结果的工作机器。
现在你选择哪个?
除非您有专门为此目的设计的视图,否则我会避免这种情况。您需要确保您的堆栈可以处理长期连接(例如,如果需要超过30秒,heroku的路由器会抱怨)或者您将需要实现一些长轮询接口。
您需要完成所有设置才能让事情上线。
拥有您想要的结果的任务将需要结果后端并传递任务ID。
您需要实现一个可以查询芹菜的视图,以确定任务在完成,成功等方面的位置。
例如
# 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将负责工作部分,您必须处理更新并通知您的客户。频道是处理后面和后面的合理方式,但你可能不需要它。
我会考虑你还需要做什么。大多数应用程序在某些时候需要异步工作,因为业务逻辑通常会指示它。如果你打算使用websockets等,但你不想将你的django应用程序分解为服务,我会咬紧牙关并做两件事。
如果您不需要多种沟通协议,只需使用芹菜并进行观看。