Django使用Celery加redis执行异步任务

 

 简单使用

安装celery及redis

 pip install celery

pip install redis

如果是win10 celery4以上还需要安装

pip install eventlet

 

定义celery任务

项目下新建celery_task/tasks.py

from celery import Celery
import time
# 创建一个Celery类的实例对象 app = Celery('celery_task.tasks', broker='redis://127.0.0.1:6379/8') # 定义任务函数 @app.task def send_register_active_email(message):
  # 耗时io操作
  time.sleep(3) with open(
"D:\\celery\\text.txt", 'a') as f: f.write("To perform a task..." + message)

 

调用触发任务

run.py

from celery_tasks.tasks import send_register_active_email


def register():
    send_register_active_email.delay("test1\n")


if __name__ == "__main__":
    register()

 

在项目目录下启动celery

celery -A celery_tasks.tasks worker -l info

win10 celery 4以上

celery -A celery_tasks.tasks worker -l info -P eventlet

再运行run.py

如图,接收到任务并成功执行。

 

 

定时任务

项目目录下创建celery_tasks包

__init__.py

# __init__.py 包初始化文件
from celery import Celery

app = Celery('demo')
app.config_from_object('celery_tasks.celeryconfig') # 通过celery 实例加载配置文件
# 自动检测
app.autodiscover_tasks(["celery_tasks.handle_upload"])

配置文件

celeryconfig.py

from datetime import timedelta
from celery.schedules import crontab

# import djcelery  # pip install djcelery 在settings apps里加入djcelery
# djcelery.setup_loader()  # 如果用到djnaog里的ORM操作
import os
import sys
import django

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "saas.settings")
django.setup()  # os.environ['DJANGO_SETTINGS_MODULE']


# 参数配置文件celeryconfig.py
BROKER_URL = 'redis://127.0.0.1:6379/1'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/2'
CELERY_TIMEZONE = "Asia/shanghai" #默认UTC
CELERY_RESULT_SERIALIZER = 'msgpack'

# 导入指定的任务模块
CELERY_IMPORTS = (
    'celery_tasks.task1',
    'celery_tasks.task2',
)

# 设置定时任务
CELERYBEAT_SCHEDULE = {
    # 每过10秒执行以下task1.add的定时任务
    'task1':{
        'task': 'celery_tasks.task1.remove_captcha',
        'schedule': timedelta(seconds=60),
        'args': ()
    },
    # 等到22点18分执行task2的multiply
    'task2': {
        'task': 'celery_tasks.task2.multiply',
        'schedule': crontab(hour=22, minute=20),
        'args': (4, 5)
    }
}

# crontab(hour='*/24'), # 每24小时执行一次
# crontab(minute=30, hour=0),  # 每天的凌晨12:30分
# crontab(hour=6, minute=0, day_of_month='1'),  # 每个月的1号的6:00启动
task1.py ORM操作,这里以删除过期的验证码为例
from celery_tasks import app
from datetime import datetime, timedelta
import pytz
# from web.models import UserInfo
from captcha.models import CaptchaStore

delta = timedelta(hours=0, minutes=1, seconds=0)
utc_tz = pytz.timezone('UTC')

# 加入装饰器变成异步的函数
@app.task
def remove_captcha():
    # 过期时间小于当前时间
    CaptchaStore.objects.filter(expiration__lt=datetime.now(tz=utc_tz)-delta).delete()

task2.py

from celery_tasks import app

@app.task
def multiply(x, y):
    print('Enter call function ...')
    return x * y

 

发送邮件

固定格式
主题:subject
正文:message,没有时为空字符串
发件人:sender
收件人:receiver
有html格式的正文:html_message
 

settings里配置发件人信息

# 发送邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# smtp服务地址
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 587
# 发送邮件的邮箱
EMAIL_HOST_USER = '123@qq.com'
# 在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = '123adfsfaf3848bcsdf3324'
# 收件人看到的发件人
EMAIL_FROM = '我的网站<123@qq.com>'
EMAIL_USE_TLS = True

 

发送邮件的任务

 send_email.py

from celery_tasks import app


@app.task
def send_register_active_email(to_email, message):
    # 耗时io操作
    # 发邮件
    subject = '欢迎注册'
    message = ''
    sender = '我的网络<123@qq.com>'
    receiver = [to_email]
    html_message = message

    send_mail(subject, message, sender, receiver, html_message=html_message)


@app.task
def send_reset_password_email(to_email, message):
   # 发邮件
    subject = '欢迎注册'
    message = ''
    sender = '我的网络<123@qq.com>'
    receiver = [to_email]
    html_message = message

    send_mail(subject, message, sender, receiver, html_message=html_message)

 

 

views视图里调用

from celery_tasks.send_email import send_register_active_email


def register(request):
    to_email = '123@qq.com'
    message = '<div>test</div>'
    send_register_active_email.delay(to_email, message)
    return JsonResponse({'status': True, 'data': 'successful'})

 

 

启动
celery -A celery_tasks worker -l info -P eventlet
celery -A celery_tasks beat -l info

 

posted @ 2020-02-19 23:19  不识少年愁  阅读(330)  评论(1)    收藏  举报