情景: 用户发起request,并等待response返回。在有些views视图处理中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等。
使用celery后,情况就不一样了。解决:将耗时的程序放到celery中执行。
Celery
celery通过消息进行通信,通常使用一个叫Broker(中间人)来协client(任务的发出者)和worker(任务的处理者). clients发出消息到队列中,broker将队列中的信息派发给worker来处理。
首先需要启动一个Broker(中间人):Redis也是一款功能完备的broker可选项,但是其更可能因意外中断或者电源故障导致数据丢失的情况。但这里还是使用redis数据库为任务队列,因为我电脑已经装了Redis数据库
sudo redis-server /etc/redis/redis.conf
# /etc/redis/redis.conf 为指定加载的redis数据配置文件
其次,在项目目录下,建立celery_tasks的python package包,在该包下创建一个tasks.py , 就可以在里面建立函数充当任务处理者worker
from celery import Celery
from django.core.mail import send_mail
import time
from django.conf import settings
# 在任务处理者加这段代码, 初始化django,这样才能导入settings.py中设置的参数
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailiyfresh.settings")
django.setup()
# 使用celery
# 创建一个Celery类的实例对象
app = Celery("celery_task.tasks", broker="redis://127.0.0.1:6379/8")
# 定义函数,也就是任务处理者
@app.task
def send_register_active_email(to_email, username, token):
"""发送激活邮件"""
# 发邮件
subject = "天天生鲜欢迎信息"
message = ''
receiver = [to_email]
html_message = '<h1>%s, 欢迎您成为天天生鲜注册会员</h1> \
请点击下面的链接激活您的账号<br/> \
<a href="http:127.0.0.1:8000/user/active/%s"> \
http:127.0.0.1:8000/user/active/%s</a>' % (username, token, token)
sender = settings.EMAIL_FROM
send_mail(subject, message, sender, receiver, html_message=html_message)
time.sleep(5)
然后就可以在其他视图中,给broker任务队列添加任务,直接调用该任务处理者就可以
例如:
from celery_tasks.tasks import send_register_active_email
send_register_active_email(["997942820@qq.com"], "shuan", token="dfajdfoiaifa")
最后在启动项目的时候,先启动celery
cd ./dailyfresh # 先cd到项目目录下
celery -A celery_tasks.tasks worker -l info