django通过celery添加异步任务
Celery特性:
异步、分布式、定时任务
Celery架构:
异步任务的重要性
大家在做web项目的时候经常会遇到一些耗时的操作, 比如: 发送邮件、发送短信、生成pdf。这些操作在某些情况下需要立即返回结果给用户,但是可以在后台异步执行。
比如用户邮箱注册的时候, 在发送邮件的时候可以先把”已经发送激活邮件到邮箱”返回给用户, 同时把邮件发送任务提交到异步处理线程中。
现在介绍一款python写的专门用于处理异步任务的框架–celery。当然celery能完成的功能远不止异步任务, 还有一个很常用的功能–定时任务
Celery简单使用
Celery是通过将代码序列然后传输到中间通信组件,这些组件可以采用任何方式实现, 这里最常用的两种是rabbitmq和redis, 然后celery的后台线程不停的从rabbitmq或者redis中读取这些任务并执行然后返回结果到这些组件,这样就实现了一个异步的功能。
Celery 用redis或者rabbitmq做消息通信,这里redis或者rabbitmq被称为中间人(Broker)Celery 系统可包含多个线程和中间人,以此获得高可用性和横向扩展能力。
环境安装:
1、redis安装: apt install redis-server , 安装完成后确认redis服务已启动。
2、celery安装:pip install -U celery[redis]
该命令会安装celery以及redis开发相关所有的依赖包。安装完成我们可以看到:
这里我们可以看到安装了billiard、pytz、vine、amqp、redis、celery等。
Celery常用命令
1、在前台启动worker: celery worker -A app -l debug
2、在后台启动worker: celery multi start worker001 -A app -l debug
3、启动任务: add.delay().get()
4、查看帮助: celery --help
创建一个简单的任务 tasks.py
from celery import Celery app = Celery("tasks", broker="redis://127.0.0.1", backend="redis://127.0.0.1" ) @app.task def add(x, y): print("runining add..") return x + y
在一台Server启动Celery Worker来监听并执行任务
celery worker -A tasks -l debug/info/warning/error/critical
在另一台Server调用任务
>>>from tasks import add >>>res = add.delay(4,4)
>>>res.ready()
True
>>>res.get() 8
在Django项目中使用Celery实现异步任务1
1、在project目录中创建celery.py和tasks.py

from __future__ import absolute_import, unicode_literals from celery import Celery app = Celery("proj", broker="redis://192.168.20.180", backend="redis://192.168.20.180", include=['proj.tasks'] ) if __name__ == "__main__": app.start()

from __future__ import absolute_import, unicode_literals from .celery import app @app.task def mul(x,y): return x * y
2、在views.py中调用tasks.py

from proj import tasks def task_test(request): res = tasks.mul.delay(2,5) return HttpResponse(res.get())
3、启动celery

celery worker -A proj -l info # start celery in the frontend celery multi start worker001 -A proj -l info # start celery in the background
在Django项目中使用Celery实现异步任务2
1、修改settings.py

TIME_ZONE = 'Asia/Shanghai' ###配置Broker BROKER_URL = 'redis://192.168.20.180:6379' BROKER_TRANSPORT = 'redis' CELERY_RESULT_BACKEND = 'redis://192.168.20.180' #CELERY_ACCEPT_CONTENT = ['application/json'] #CELERY_TASK_SERIALIZER = 'json' #CELERY_RESULT_SERIALIZER = 'json' #CELERY_TIMEZONE = TIME_ZONE
2、需要在settings.py同一级目录中创建 celery.py

from __future__ import absolute_import import os import django from celery import Celery from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MxOnline.settings') django.setup() app = Celery('MxOnline') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
3、在对应的app目录下创建tasks.py

from MxOnline.celery import app @app.task def send_register_email(email, send_type="register"): email_record = EmailVerifyRecord() if send_type == "update_email": code = random_str(4) else: code = random_str(16) email_record.code = code email_record.email = email email_record.send_type = send_type email_record.save() email_title = "" email_body = "" if send_type == "register": email_title = "慕学在线网注册激活链接" email_body = "请点击下面的链接激活你的账号: http://www.imooc.com/active/{0}".format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass elif send_type == "forget": email_title = "慕学在线网注册密码重置链接" email_body = "请点击下面的链接重置密码: http://www.imooc.com/reset/{0}".format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass elif send_type == "update_email": email_title = "慕学在线邮箱修改验证码" email_body = "你的邮箱验证码为: {0}".format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass
4、编辑views.py文件完成邮件发送异步调用

#coding:utf-8 from django.shortcuts import render from django.http import HttpResponse from .tasks import send_register_email def index(request): send_register_email.delay() return HttpResponse(u"邮件发送成功, 请查收")
5、启动worker服务,监听执行任务

celery worker -A MxOnline -l info -f logfile
在Django项目中使用Celery实现计划任务
1、install package: pip install django-celery-beat
2、add the "django_celery_beat" module to settings.py "INSTALLED_APPS"
3、apply django database migrate: python manage.py migrate
4、根据上面《在Django中使用Celery实现异步任务》 编写celery.py(放在sttings.py同一级目录)与tasks.py(放在每个app下)
5、启动celery: celery beat -A proj -S django -l info
6、在Django admin中制定计划任务
注意,经测试,每添加或修改一个任务,celery beat都需要重启一次,要不然新的配置不会被celery beat进程读到.
另外,Celery提供了一个工具flower,将各个任务的执行情况、各个worker的健康状态进行监控并以可视化的方式展现,如下图所示:
未完待续...