使用场景:
1. 异步任务时候用,如发送验证码(不能是同步操作)
2. 定时任务时候用
要实现的效果:
同步任务,减少阻塞时间,直接给用户响应。
异步流程:
配置前提:
1. 需要安装好redis
2. 安装好模块,celery、redis模块
异步任务配置:
1. settings同级目录创建文件celery.py
from __future__ import absolute_import, unicode_literals import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'integral_mall.settings') # 设置django环境 app = Celery('integral_mall') # 项目名 app.config_from_object('django.conf:settings', namespace='CELERY') # 使用CELERY_ 作为前缀,在settings中写配置 app.autodiscover_tasks() # 发现任务文件每个app下的task.py
# 标红地方需要改成项目名称
2. settings添加celery配置
# celery配置 CELERY_BROKER_URL = 'redis://:redis密码@redis机器ip:redis端口/redis库' # Broker配置,使用Redis作为消息中间件 CELERY_RESULT_BACKEND = 'redis://:redis密码@redis机器ip:redis端口/redis库' # 存储执行结果或报错信息,redis形式,比较乱,注释掉就不存执行信息了
CELERY_RESULT_SERIALIZER = 'json' # 结果序列化方案
演示:
注意:如果redis没有配置密码: 'redis://redis机器ip:redis端口/redis库'
3. setting同级__init__.py文件添加内容
from __future__ import (absolute_import, unicode_literals) from .celery import app as celery_app __all__ = ['celery_app']
4. 在网站应用下创建tasks.py文件
# 目录演示
from __future__ import absolute_import, unicode_literals from celery import shared_task @shared_task def send_veri_code(phone, code): from twilio.rest import Client account_sid = "*******" auth_token = "******" client = Client(account_sid, auth_token) client.messages.create( to="+86" + phone, from_="+142********", body="来自***提示! 您的验证码是:%s" % code )
# 发送验证码的异步任务
5. 视图中触发任务
from all import tasks
6. 启动celery
celery -A integral_mall.celery worker -l info --autoscale=3,1
-A celery文件相对路径 :指定celery路径
-l debug|info|... : 日志输出的等级,debug最低表示全部输出
-c 数量 : 表示指定固定的worker数量,默认是cpu数量(开多了浪费资源)
--autoscale=5,2 : 表示指定最低和最高开启的worker数量,最低2个,最多5个,灵活,根据任务数量启动销毁woker
-P gevent : 并发模式改成协程,由于默认是多进程消耗资源多,在任务是非cpu密集型任务时候,用协程可以减少资源消耗,注意需要安装模块pip install gevent
注意:
1. 每次修改tasks文件内容,都需要重新启动celery
2. ctrl+c如果无法结束,打开任务管理器找到celery.py结束掉即可
celery支持三种并发模式:perfork(多进程,默认)、threading、协程(gevent、eventlet)
协程是微量级进程,操作系统不知道它的存在,是程序级别的,不是计算密集型任务,用协程可合理利用资源。
发送邮件:https://www.cnblogs.com/zezhou/p/11273046.html
发送短信:https://www.cnblogs.com/zezhou/p/13157039.html
定时任务、执行结果mysql存储参考:https://www.cnblogs.com/wdliu/p/9530219.html
定时任务(一次性任务):
注:无法修改,只能简单得加个时间,定时执行
配置跟上面得一样即可。
任务写法:
调用写法:
now_time = datetime.now() # 需要转换成utc时间 utc_time = datetime.utcfromtimestamp(now_time.timestamp()) target_utc_time = utc_time + timedelta(seconds=60) # 60秒后执行 result = task.send_expire_tips.apply_async(args=[1, "zezhou"], eta=target_utc_time)
# eta是执行时间