安居客住房系统-基于Python-Django前后端分离开发(五)—— 消息队列的应用和celery异步化操作

消息队列的应用和celery异步化操作

Django中的中间件用更准确的方法应该称为拦截过滤器。消息队列能够解决消息传递的问题,分为两种模式:点到点传递、发布订阅。对于网站的优化的两大定律,第一定律就是使用缓存,通过空间换时间的模式;第二定律就是使用消息队列,主要解决解耦、削峰和异步化的问题。由于队列是先进先出,所以消息队列还能够保证顺序性。比如像电商网站的下订单和受理订单,消息队列就能做到上游节点和下游节点的解耦合。

消息队列产品:对于Redis,并不是专业的消息队列服务器,但是Redis的List类型可以用来实现消息队列服务,通过lpush + rpop或者rpush + blpop就能实现将列表改造为队列。RabbitMQ:爱立信;Kafka; RockeMQ;ActiveMQ。

业务背景

在上传文件到七牛云的过程中,可能需要验证文件,生成日志,就需要花费较多的时间,为了不让耗时间的任务堵塞后面的任务,将此任务交给其他进程来处理而当前进程不会被阻塞,当前的线程则可以立马给用户响应。由于耗时间的任务对接可能不稳定的三方平台,所以需要进行异步化处理。在Django中就可以使用Celer来进行异步化的操作。

使用celery

# 这里推荐直接安装celery,而不使用django-celery
pip install celery -i https:pypi.doubanio.com/simple

创建celery对象进行异步化处理

这里我将celery对象直接放在Django项目的__init__文件中。创建好了celery()对象中,添加如下参数

import celery

app = celery.Celery('izufang',
                    broker='',
                    backend='')
# 发现需要异步化的任务
app.autodiscover_tasks(['common', ])
  1. izufang这个名称是当前celery对象对应的文件的名称,由于将其放在__init__文件中,所以这里直接传入izufang,若celery对象创建在izuanfg/foo.py文件中,这里的第一个参数需要写izufang.foo

  2. borker:提供消息队列服务的对象

  3. backend:消息执行结果的持久化地址

  4. 由于发送短信验证码和上传七牛云的图片都写在commom模块下,所以通过app.autodiscover_tasks(['common', ])找到需要这个包下面需要异步化执行的任务。

  5. 在需要异步化的任务前面,需要打上装饰器@app.task

    @app.task
    def send_sms_by_aliyun(tel, code):
        """发送短信验证码,阿里云网关"""
    	pass
    
    @app.task
    def upload_file_to_qiniu(file_path, filename):
        """将文件上传到七牛云存储"""
        pass
    
    @app.task
    def upload_stream_to_qiniu(file_stream, filename, size):
        """将数据流上传到七牛云存储"""
        pass
    
  6. 在视图函数中,对需要放入消息队列的操作,添加一个delay方法让函数异步化执行

    @api_view(('GET', ))
    def get_code_by_sms(request, tel):
        """获取短信验证码"""
        # ...
        # 通过异步化函数的delay方法让函数异步化执行(放入消息队列)
                send_sms_by_aliyun.delay(tel, code)
                
    

    假如发送短信功能有延迟,这样就能够推迟执行,不会阻塞后面的任务。即使下游节点崩溃掉,放入消息队列的任务依然存在。

配置好了上面的操作,当我们重启项目再次请去api/mobile/<tel>就能够返回响应

在这里插入图片描述

但是返回了响应,消息不会立马发送给用户,而是存在了消息队列中,我们在redis服务器中可以查看

127.0.0.1:54321> select 1
OK
127.0.0.1:54321[1]> keys *
1) "celery"
2) "_kombu.binding.celery"
127.0.0.1:54321[1]> type celery
list
127.0.0.1:54321[1]> lrange celery 0 -1

异步化任务的受理

在上面发送了短信之后,发送短信任务已近存入消息队列当中,这是需要受理了这个任务,才能成功发送短信。对于发送任务的机器和受理任务的机器可以是两台不同的机器,若要受理任务,需要先完善__init__中的代码

import os

import celery

from izufang import settings

# 加载环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'izufang.settings')

# 创建celery对象,指定模块、消息队列和持久化方式
app = celery.Celery('izufang',
                    broker='redis://:5201314@Dcs@121.199.18.215:54321/1',
                    backend='redis://:5201314@Dcs@121.199.18.215:54321/2')

# 从配置文件中读取Celery相关配置
app.config_from_object('django.conf:settings')
# 发现需要异步化的任务
app.autodiscover_tasks(['common', ])

在终端中可以执行如下代码:

celery -A izufang worker -l debug

就可以完成短信的发送了


感谢大家的阅读,我会持续更新❤❤

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代__-__代

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值