当前位置:网站首页>django-celery-redis异步发邮件
django-celery-redis异步发邮件
2022-07-28 10:12:00 【Code Hamal】
Django-Celery-Redis异步发邮件
python == 3.7.6
django == 2.1.8
celery == 4.4.7
redis == 3.5.3
eventlet == 0.26.1
什么是celery
Celery是一个功能完备即插即用的任务队列。它使得我们不需要考虑复杂的问题,使用非常简单。celery适用异步处理问题,当发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作,我们可将其异步执行,这样用户不需要等待很久,提高用户体验。 celery的特点是:
- 简单,易于使用和维护,有丰富的文档。
- 高效,单个celery进程每分钟可以处理数百万个任务。
- 灵活,celery中几乎每个部分都可以自定义扩展。
celery核心
1、Task
任务(Task)就是你要做的事情,例如一个注册流程里面有很多任务,给用户发验证邮件就是一个任务,这种耗时任务可以交给Celery去处理,还有一种任务是定时任务,比如每天定时统计网站的注册人数,这个也可以交给Celery周期性的处理。
2、Broker
Broker 的中文意思是经纪人,指为市场上买卖双方提供中介服务的人。在Celery中它介于生产者和消费者之间经纪人,这个角色相当于数据结构中的队列。例如一个Web系统中,生产者是处理核心业务的Web程序,业务中可能会产生一些耗时的任务,比如短信,生产者会将任务发送给 Broker,就是把这个任务暂时放到队列中,等待消费者来处理。消费者是 Worker,是专门用于执行任务的后台服务。Worker 将实时监控队列中是否有新的任务,如果有就拿出来进行处理。Celery 本身不提供队列服务,一般用 Redis 或者 RabbitMQ 来扮演 Broker 的角色
3、Worker
Worker 就是那个一直在后台执行任务的人,也称为任务的消费者,它会实时地监控队列中有没有任务,如果有就立即取出来执行。
4、Beat
Beat 是一个定时任务调度器,它会根据配置定时将任务发送给 Broker,等待 Worker 来消费。
5、Backend
Backend 用于保存任务的执行结果,每个任务都有返回值,比如发送邮件的服务会告诉我们有没有发送成功,这个结果就是存在Backend中,当然我们并不总是要关心任务的执行结果。

Broker选择
Celery需要一种解决消息的发送和接受的方式,我们把这种用来存储消息的的中间装置叫做message broker, 也可叫做消息中间人。 作为中间人,我们有几种方案可选择:
RabbitMQ
RabbitMQ是一个功能完备,稳定的并且易于安装的broker. 它是生产环境中最优的选择。
使用RabbitMQ的细节参照以下链接: http://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html#broker-rabbitmq
Redis
Redis也是一款功能完备的broker可选项,但是其更可能因意外中断或者电源故障导致数据丢失的情况。
Redis作为Broker,可访下面网址: http://docs.celeryproject.org/en/latest/getting-started/brokers/redis.html#broker-redis
将redis发布订阅模式用做消息队列和rabbitmq的区别:
可靠性
redis:没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失, 不会存在内存中;rabbbitmq: 具有消息消费确认机制,如果发布一条消息,还没有消费者消费该队列,那么这条消息将一直存放在队列中,直到有消费者消费了该条消息,以此可以保证消息的可靠消费。
实时性
redis实时性高,redis作为高效的缓存服务器,所有数据都存在在服务器中,所以它具有更高的实时性消费者负载均衡;rabbitmq队列可以被多个消费者同时监控消费,但是每一条消息只能被消费一次,由于rabbitmq的消费确认机制,因此它能够根据消费者的消费能力而调整它的负载,redis发布订阅模式,一个队列 可以被多个消费者同时订阅,当有消息到达时,会将该消息依次发送给每个订阅者;
持久性
redis:redis的持久化是针对 于整个redis缓存的内容,它有RDB和AOF两个持久化方式,可以将整个redis实例持久化到磁盘,以此来做数据备份,防止异常情况下导致数据丢失。rabbitmq:队列、消息都可以选择性持久化,持久化粒度更小,更灵活;队列监控rabbitmq实现了后台监控平台,可以在该平台上看到所有创建的队列的详细情况,良好的台后管理平台可以方便我们更好的使用;redis没有所谓的监控平台。
总结:
redis:轻量级、低延迟,高并发、低可靠性;
rabbitmq:重量级、高可靠,异步,不保证实时
在Django中使用celery
django项目名称:celery_test
在django项目celery_test/celery_test/下创建celery.py文件,配置以下内容:
# celery.py文件
import os
from celery import Celery
# 把celery和django进行组合,识别和加载django的配置文件
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'celery_test.settings')
# 创建celery实例
app = Celery('celery_test')
# 指定celery消息队列的配置
app.config_from_object('celery_test.config', namespace='CELERY')
# 从所有的django-app中加载任务
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
在django项目celery_test/celery_test/下创建config.py文件,配置以下内容:
# 消息中间人设置
broker_url = 'redis://127.0.0.1:6379/15'
# 结果存储设置
result_backend = 'redis://127.0.0.1:6379/14'
在django项目celery_test/celery_test/下__init__.py中写入以下内容:
# 绝对引用,使我们的celery模块不会与原始的celery冲突
from __future__ import absolute_import, unicode_literals
# 加入绝对引入以后,导入当前模块下的内容方法: from xx import xx as xx
from .celery import app as celery_app
__all__ = ('celery_app',)
在settings.py中配置发邮件的内容:
# 配置邮件发送
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com' # 如果为163邮箱,设置为smtp.163.com
EMAIL_PORT = 25 # 或者 465/587是设置了 SSL 加密方式
# 发送邮件的邮箱
EMAIL_HOST_USER = '3735***[email protected]'
# 在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'xxxxxxxxxxxxx' # 第三方登陆使用的授权密码
EMAIL_USE_TLS = True # 这里必须是 True,否则发送不成功
# 收件人看到的发件人, 必须是一直且有效的
EMAIL_FROM = '海上明月<3735***[email protected]>'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
在django的app中创建tasks.py文件,在这里写入异步任务内容:
# 绝对引用,使我们的celery模块不会与原始的celery冲突
from __future__ import absolute_import, unicode_literals
# 导入原始的celery模块中shared_task from xx import xx
from celery import shared_task
# 使用django内置函数发送邮件
from django.core.mail import send_mail
# 导入django的settings
from django.conf import settings
@shared_task
def send_mail_task(usernaem, email, token):
""" 使用django内置函数发送邮件 """
subject = "海上明月"
message = ""
sender = settings.EMAIL_FROM
recipient = [email]
html_message = "<h1>{},欢迎您注册,请点击以下链接进行激活邮箱:<a href='http://127.0.0.1:8000/api/v1/active/{}'>点击这里进行激活</a></h1>".format(username, token)
send_mail(subject, message, sender, recipient, html_message=html_message)
在django的app下的views.py中调用tasts下的任务
from django.views import View
from django.http import JsonResponse
from .tasks import send_mail_task
from itsdangerous import TimedJSONWebSignatureSerializer
from django.conf import settings
# 发送邮件
token_serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 600)
class SendMailView(View):
def post(self, request):
username = 'Edward'
email = '3706***[email protected]'
user_info = {
'user_id': '1'}
token = token_serializer.dumps(user_info).decode()
send_mail_task.delay(username, email, token)
return JsonResponse({
'msg': 'OK'})
邮件发送成功以后,通过get方式获取用户的token
from django.views import View
from django.http import JsonResponse
from itsdangerous import TimedJSONWebSignatureSerializer, SignatureExpired
from django.conf import settings
# 发送邮件
token_serializer = TimedJSONWebSignatureSerializer(settings.SECRET_KEY, 600)
class ActiveView(View):
""" 激活用户 """
def get(self, request, token):
try:
user_info = token_serializer.loads(token)
return JsonResponse({
'msg': '激活成功', 'code': 200})
except SignatureExpired:
return JsonResponse({
'msg': '激活链接失效,请重新发送邮件进行激活', 'code': 404})
启动celery
打开pycharm下的Terminal,进入到项目根目录下,使用eventlet启动celery
celery -A celery_test worker -l info -P eventlet
边栏推荐
猜你喜欢

Match file names from file paths using regular expressions

利用正则表达式从文件路径中匹配文件名

定了!就在7月30日!

SuperMap iServer发布管理以及调用地图服务

14、双指针——盛最多水的容器

6. Double pointer -- the sum of the two numbers of the incremental array is equal to the target number

Aqua Data Studio 18.5.0导出insert语句

PHP生成二维码(学习)

gcc: error trying to exec 'as': execvp: No such file or directory

SQL Server 2016 学习记录 --- 数据更新
随机推荐
8、数组中出现次数超过一半的数字
排序——快速排序(快慢指针实现)
Aqua Data Studio 18.5.0导出insert语句
Small knowledge in Oracle
15、判断二维数组中是否存在目标值
PHP generates QR code (learning)
Summary of key points of bank entry examination
Go 内存模型 (2014年5月31日版本)
Redis design specification
12. Double pointer -- merge two ordered linked lists
JVM principle
SQL Server 2016 学习记录 ---视图
SQL Server 2016 学习记录 --- 数据更新
Huawei takes a 10% stake in fullerene technology, a graphene material manufacturer
IE兼容性问题处理
【微信小程序】项目实战—抽签应用
在mt6735中添加新的开机logo与开\关机动画
Qt | 信号和槽的一些总结
胡润发布2020中国芯片设计10强民营企业:华为海思竟然没有上榜!
Prometheus 运维工具 Promtool (四)TSDB 功能