Django-Celery

问题

  • 用户发起request,并等待response返回。在views中,可能需要执行一段耗时的程序,那么用户就会等好长时间,造成不良好的用户体验
  • 网站每小时需要同步一次天气信息,但是http请求是需要触发的,难道要一小时请求一次吗?

解决

  • 使用celery
    • 将耗时操作放到celery中执行
    • 使用celery定时执行

celery

  • **任务task:**就是一个python函数
  • **队列queue:**将要执行的任务加入到队列中
  • **工人worker:**在一个新进程中,负责执行队列中的任务
  • **代理broker:**负责调度,在布置环境中使用redis

问题示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="/register/" method="post">
{% csrf_token %}
<input type="text" name="username" value=""><br>
<input type="password" name="password" value=""><br>
<input type="submit" value="注册">
</form>
</body>
</html>

安装

1
pip install celery==3.1.25
1
pip install celery-with-redis==3.0
1
pip install django-celery==3.2.1
  • 注册应用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myApp',
    'tinymce',
    'djcelery',
    ]
  • settings.py末尾添加以下代码

    1
    2
    3
    4
    5
    6
    7
    8
    # celery
    import djcelery

    djcelery.setup_loader()
    # 指定redis数据库
    BROKER_URL = 'redis://:密码@127.0.0.1:6379/0'
    # 指定任务文件
    CELERY_IMPORES = ("myApp.task")

在应用目录下创建task.py文件,用于书写任务

1
2
3
4
5
6
7
8
9
import time
from celery import task


@task
def longIO():
print("开始耗时操作……")
time.sleep(10)
print("结束耗时操作……")

在工程目录下的project目录下创建一个名为celery.py的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from __future__ import absolute_import

import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings')

app = Celery('portal')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))

在工程目录下的project目录下的__init__.py文件中添加

1
from project.celery import app as celery_app

迁移

  • 生成celery需要的数据表

    1
    python manage.py migrate

将任务添加到队列

1
2
3
4
5
6
7
8
9
10
11
from myApp.task import longIO


def register(request):
if request.method == "GET":
return render(request, "myApp/register.html")
else:
username = request.POST.get("username")
passwd = request.POST.get("passwd")
longIO.delay()
return HttpResponse("注册成功!!")

启动redis

1
redis-server.exe redis.windows.conf

启动worker

1
python manage.py celery worker --loglevel=info

启动Django服务

1
python manage.py runserver
本文结束 感谢您的阅读
正在加载今日诗词....