Django中异步方案RabbitMQ和Celery
RabbitMQ
1.生产者消费者设计模式
- 最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联。我们称这一解耦方式为:生产者消费者设计模式
总结:
生产者生成消息,缓存到消息队列中,消费者读取消息队列中的消息并执行。
2.RabbitMQ介绍
- RabbitMQ是消息队列,消息队列是消息在传输过程中保存消息的容器
- 现在主流的消息队列有:RabbitMQ、ActiveMQ、Kafka等
- RabbitMQ和ActiveMQ比较
- 系统吞吐量:RabbitMQ好于ActiveMQ
- 持久化消息:RabbitMQ和ActiveMQ都支持
- 高并发和可靠性:RabbitMQ好于ActiveMQ
- RabbitMQ和Kafka比较
- 系统吞吐量:RabbitM弱于Kafka
- 可靠性和稳定性:RabbitMQ好于Kafka
- 设计初衷:Kafka是处理日志的,是日志系统,所以并没有具备一个成熟MQ应该具备的特性。
- RabbitMQ和ActiveMQ比较
- 综合考虑:选择RabbitMQ作为消息队列
3.安装RabbitMQ
1.安装Erlang(以windows为例)
由于 RabbitMQ 是采用 Erlang 编写的,所以需要安装 Erlang 语言库。
erlang下载
download win64安装erlang
使用下载资源exe执行安装后,记录安装的目录文件夹路径,例如:D:\software\Erlang配置环境变量
计算机–>属性–>高级系统配置–>高级–>环境变量–>系统变量–>Path 追加路径 D:\software\Erlang\erl9.3\bin测试erlang是否安装成功
以管理员运行命令提示,cmd到erlang文件夹bin目录下,输入
erl
出现下图则安装成功
2.安装RabbitMQ
- 下载RabbitMQ软件,RabbirMQ下载地址,官方推荐的最新版本rabbitmq-server-3.7.7.exe
- 安装
下载完成后双击.exe进行安装,安装成功后,默认是启动状态,建议将与erlang放在同一个大目录下,紧挨在一起。- 安装管理桌面的插件,可以通过浏览器登录查看消息队列状态和交换机的工作情况等信息的管理页面,类似于tomcat的管理页面
在rabbitmq的安装目录下找到sbin目录,进入并在此目录打开cmd窗口(进入sbin的cmd窗口),输入以下命令rabbitmq-plugins enable rabbitmq_management
如图:
- 打开web管理页面
在浏览器输入http://localhost:15672进行验证,你会看到下面界面,输入用户名:guest,密码:guest你就可以进入管理界面!
4.Python访问RabbitMQ
- RabbitMQ提供默认的administrator账户
- 用户名和密码:guest、guest
- 协议:amqp
- 地址:localhost
- 端口:5672
- 查看队列中的消息:sudo rabbitctl list_queues
安装pika
# Python3虚拟环境下,安装pika
$ pip install pika
Celery
1.Celery介绍
- 介绍
- 一个简单、灵活且可靠、处理大量消息的分布式系统,可以在一台或者多台机器上运行。
- 单个Celery进程每分钟可处理数以百万计的任务。
- 通过消息进行通信,使用消息队列(broker) 在客户端和消费者之间进行协调。
- 安装 Celery
$ pip install -U Celery
2.celery构成
- 任务task:耗时的代码
- 队列queue:将任务放到队列中,逐个执行
- 工人worker:从队列中取任务执行,本质就是一个新线程、进程、协程
- 代理人broker:指定队列存储到哪里去
3.实现过程(以发短信验证为例)
一、创建celery并加载配置
- 1、新建celery_tasks包,用于写任务的代码
- 2、新建main.py,创建celery对象
celery_tasks.main.py
# 启动celery启动文件
from celery import Celery
import os
# 读取django项目的配置
os.environ["DJANGO_SETTINGS_MODULE"] = "meiduo_mall.settings.dev"
# 创建celery对象
app = Celery("meiduo")
- 3、加载配置:新建config.py,指定配置,当前指定为rabbitmq为队列
celery_tasks.config.py
# 指定rabbitmq作为celery的队列
broker_url = "amqp://guest:[email protected]:5672"
celery_tasks.main.py
# 加载celery配置
app.config_from_object("celery_tasks.config")
二、定义发送短信任务
- 4、新建sms包,在sms包下新建tasks.py,在这个文件中写任务代码
- 5、定义方法send_sms,剪切耗时代码,添加装饰器@app.task()
from celery_tasks.main import app
from meiduo_mall.libs.yuntongxun.sms import CCP
from . import constants
# bind:保证task对象会作为第一个参数自动传入
# name:异步任务别名
# retry_backoff:异常自动重试的时间间隔 第n次(retry_backoff*2^(n-1))s
@app.task(bind=True, name='send_sms', retry_backoff=3)
# 将耗时的代码封装在一个方法中
def send_sms(self,mobile, sms_code):
# 发短信
ccp = CCP()
ret = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRES], 1)
if ret != 0:
# max_retries:异常自动重试次数的上限
# Python中的raise 关键字用于引发一个异常
raise self.retry(exc=Exception("发送短信失败"), max_retries=3)
return ret
三、 调用:任务.delay(参数)
from celery_tasks.sms.tasks import send_sms
# 通过delay调用,可以将任务加到队列中,交给celery去执行
send_sms.delay(mobile, sms_code)
- 四、启用Celery服务
celery -A celery_tasks.main worker -l info