Django - 如何在 celery 和 redis 中使用异步任务队列
Posted
技术标签:
【中文标题】Django - 如何在 celery 和 redis 中使用异步任务队列【英文标题】:Django - How to use asynchronous task queue with celery and redis 【发布时间】:2015-11-14 13:47:54 【问题描述】:#In my views.py file
pi1 = None
pis1 = None
def my_func():
#Essentially this function sets a random integer to pi1 and pis1
global pi1, pis1
pi1 = randint(0,9)
pis1 = randint(0,9)
return
def index(request):
my_func()
context =
"pi1" : pi1,
"pis1" : pis1,
return render(request, "index.html", context)
#In the index.html file
<h1> pi1 </h1>
<h1> pis1 </h1>
为了简单起见,我删除了很多代码,但这就是它的要点。尽管我为 my_func 发布了代码,但它是一个耗时的函数,它会导致 index.html 在被访问时加载一段时间。如何使用 celery 和 redis 在后台运行 my_func 以便 index.html 加载更快?
我已阅读 celery 文档,但我仍然无法设置 celery 和 redis。谢谢。
【问题讨论】:
这样:context = "pi1" : pi1, "pis1" : pis1, 工作吗? 一切正常,只是速度很慢。 【参考方案1】:如前所述,您可能不需要芹菜。这是从案例 2 派生的示例:https://zapier.com/blog/async-celery-example-why-and-how/。它完全适合我:
from time import sleep
import json
from django.http import HttpResponse
from django.shortcuts import render
def main_view(request):
return render(request, 'index.html')
def ajax_view(request):
sleep(10) #This is whatever work you need
pi1 = "This is pi1" #I just made pi1/pis1 random values
pis1 = "This is pis1"
context =
"pi1" : pi1,
"pis1" : pis1,
data = json.dumps(context)
return HttpResponse(data, content_type='application/json')
我的 index.html 包含:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Main View</title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).ready(function()
$.ajax(
url: "/test_ajax/",
).done(function( data)
$("#pi1").text(data.pi1);
$("#pis1").text(data.pis1);
);
);
</script>
</head>
<body>
<h1 id = "pi1">Loading</h1>
<h1 id = "pis1">Loading</h1>
</body>
</html>
我的 urls.py 包含:
from django.conf.urls import include, url
from django.contrib import admin
from testDjango.test import main_view, ajax_view
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^test/', main_view),
url(r'^test_ajax/', ajax_view)
]
当我访问 localhost:8000/test/ 时会发生什么我立即看到:
大约 10 秒后,我看到了:
这个想法是您立即返回您的页面并使用 jquery 在完成时获取操作结果并相应地更新您的页面。您可以添加更多内容,例如进度条/加载图像等。例如,您可以在后台对pi1
和pis
进行处理,并在完成后将其加载到 HTML 中。
【讨论】:
谢谢你的想法,但你能解释一下javascript部分吗?我不明白你在那里做什么。 另外,在阅读了您链接的页面后,我的印象是这不会更快地加载我的页面,但它只会让我在页面上添加一个加载栏。 让我们为此添加一些数字。如果您的pi1
和 pis1
需要大约 10 秒的时间来计算。您必须在某个时间点花费 10 秒的时间来计算。除非您已经有缓存值,否则您无法真正避免这种情况。从我展示的链接中,如果你不使用任何异步的东西,用户必须提前等待这 10 秒。当他们看到一个空白页面时,他们必须等待 10 秒。 async 的作用是让您显示某些内容,并在用户等待 10 秒时将页面控制权交还给用户。这意味着不再有空白页,这使它变得更好。
Celery 不会让你避免等待这 10 秒,而不是使用这样的东西。芹菜的好处来自于你需要做很多工作的时候。如果你只是偶尔需要一件东西,那真的不需要。无论如何,在我的示例中,javascript 所做的是,当页面加载时,它使用 AJAX 发送请求以获取 pis
和 pi1s` 的信息,然后用 @ 的值填充 s 987654335@ 和 pis1
在你进行了 10 秒的计算之后。这样,用户将获得他们想要的信息,而无需一直看着空白屏幕。
JSON 是一种数据格式。它不是特定于javascript的。我把它放到 JSON 中,因为它相当容易阅读并且是可移植的。 jQuery 是一个方便的 javascript 包。它有一个名为.ajax
的函数,这是我用过的。您可以在这里阅读有关 ajax 的基本概念:learn.jquery.com/ajax【参考方案2】:
这里不需要芹菜。您可以使用 AJAX 请求在页面上加载这些值。您应该创建一个单独的视图来计算这些值,并在加载 index.html 后使用 javascript 调用它。
【讨论】:
我很困惑,你能给我举个例子吗?谢谢。以上是关于Django - 如何在 celery 和 redis 中使用异步任务队列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Django 中使用 Celery 上传和处理大型 excel 文件?
如何在任务中获取芹菜结果模型(使用 django-celery-results)