Django+celery+redis 异步发送邮件功能
系统==win10
Django==2.1
redis== 3.2.0
celery==4.2.1
由于目前是在开发过程中,所以测试环境为win10。
开发需求:当用户在页面点击“下载时”,系统会通过用户session获取用户邮箱,使用系统设置的邮箱发送给用户包含指定文件的邮件。
问题1:views.py中,除非系统将邮件已成功发送,才会return页面给用户,由于文件大小和网络环境的问题,发送时间可能较长,不可能让用户长时间等待。
问题2:系统发送邮件的主进程进行时,用户和其他人都无法做新的操作。
解决办法:使用celery将发送邮件的任务转成异步执行,无需用户等待。使用redis作为队列,将异步任务进行缓存。不影响服务器主进程。
开始解决之路:
部署环境
pip3 install redis (这里首先需要下载redis安装,下载链接https://github.com/MicrosoftArchive/redis/releases,进入后下载Redis-x64-3.2.100.zip),启动命令: 进入解压后的文件 输入:redis-server.exe redis.windows.conf
pip3 install celery
目录结构见下图:
将创建两个py文件,tasks.py和celery.py。
tasks.py 内容
from django.conf import settings from django.core.mail import EmailMessage from Scitylab.celery import app @app.task def send_mail(): print('**************开始生成消息*****************') subject = 'test' text_content = '这是一封重要的报告邮件.' from_email = settings.EMAIL_HOST_USER msg = EmailMessage(subject, text_content, from_email, ['*******@qq.com', ]) msg.send(fail_silently=False)
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','Scitylab.settings') django.setup() app = Celery('Scitylab') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
setting.py 添加的内容为
BROKER_URL = 'redis://localhost:6379/0' BROKER_TRANSPORT = 'redis'
views.py内容为
from django.shortcuts import render, redirect from website import models from .tasks import send_mail def download(req): if req.method == "POST": send_mail.delay() return redirect('/html/download/') return render(req, "download.html")
django 启动项目(命令:python manage.py runserver 0.0.0.0:8000)后,开启redis数据库(命令:redis-server.exe redis.windows.conf),然后开发celery服务(命令:celery -A Scitylab worker -l debug)
到此为止,还有一个问题,由于测试环境为win10,celery4.2是不支持win10的,所以,还需要执行pip3 install gevent (因为啥我也不知道,google出来的),将celery开启worker的命令改为:celery -A Scitylab worker -l debug -P gevent
有什么问题请随时联系,邮箱1005819387@qq.com,非常欢迎技术交流