Loading

在Django中应用消息队列

在Django中应用消息队列,一般有以下步骤和方式:

选择消息队列系统

常见的消息队列系统有RabbitMQ、Redis、Kafka等 ,各有特点:

  • RabbitMQ:基于AMQP协议,可靠性高、功能丰富,适合构建分布式、高并发系统。在电商、金融等对数据可靠性要求高的场景广泛应用。
  • Redis:性能卓越,支持多种数据结构。适用于对性能要求极高、数据量相对较小且对消息持久化要求不特别严格的场景,像简单的任务队列、缓存更新通知等。
  • Kafka:高吞吐量、可扩展性强,常用于大数据领域和处理海量消息的场景,如日志处理、实时数据采集等。

安装相关库

以RabbitMQ为例,需安装用于Python与RabbitMQ通信的pika库,命令为pip install pika ;若用Redis,可安装redis-py ,命令是pip install redis ;使用Kafka则安装kafka-python ,即pip install kafka-python

配置消息队列连接

在Django项目的settings.py中配置连接信息。比如RabbitMQ:

RABBITMQ_URL = 'amqp://guest:guest@localhost:5672/'

Redis配置示例:

REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 0

发送消息

以RabbitMQ为例,在视图函数或其他业务逻辑中发送消息:

import pika
from django.conf import settings

def send_message(request):
    connection = pika.BlockingConnection(pika.URLParameters(settings.RABBITMQ_URL))
    channel = connection.channel()
    channel.queue_declare(queue='my_queue') 
    message = "hello,rabbitmq!"
    channel.basic_publish(exchange='', routing_key='my_queue', body=message)
    connection.close()
    return HttpResponse("Message sent!")
# 定义一个名为 send_message 的视图函数,用于处理 HTTP 请求
def send_message(request):
    # 使用 pika 库创建一个到 RabbitMQ 服务器的阻塞连接
    # pika.URLParameters(settings.RABBITMQ_URL) 根据 Django 配置文件中的 RABBITMQ_URL 来解析连接参数
    # 例如 RABBITMQ_URL 可能是 'amqp://guest:guest@localhost:5672/'
    connection = pika.BlockingConnection(pika.URLParameters(settings.RABBITMQ_URL))
    
    # 从连接中创建一个通道,所有与消息队列的交互都通过通道进行
    channel = connection.channel()
    
    # 声明一个队列,如果该队列不存在则创建它
    # 这里声明的队列名为 'my_queue',确保在发送消息前队列已经存在
    channel.queue_declare(queue='my_queue')
    
    # 定义要发送的消息内容
    message = "hello,rabbitmq!"
    
    # 使用通道的 basic_publish 方法将消息发布到 RabbitMQ
    # exchange 参数指定消息要发送到的交换器,这里为空字符串表示使用默认交换器
    # routing_key 参数指定消息的路由键,这里设置为队列名 'my_queue',表示消息将被发送到该队列
    # body 参数是要发送的消息内容
    channel.basic_publish(exchange='', routing_key='my_queue', body=message)
    
    # 关闭与 RabbitMQ 服务器的连接,释放资源
    connection.close()
    
    # 返回一个 HTTP 响应,告知客户端消息已成功发送
    return HttpResponse("Message sent!")

上述代码连接到RabbitMQ服务器,声明队列,然后发送消息。

消费消息

可以编写独立脚本或使用Django管理命令来消费消息。例如,RabbitMQ消费脚本:

import pika
from django.conf import settings

def callback(ch, method, properties, body):
    print(f"Received message: {body.decode()}")

def consume_messages():
    connection = pika.BlockingConnection(pika.URLParameters(settings.RABBITMQ_URL))
    channel = connection.channel()
    channel.queue_declare(queue='my_queue')
    channel.basic_consume(queue='my_queue', on_message_callback=callback, auto_ack=True)
    print('Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

if __name__ == '__main__':
    consume_messages()
# 导入 pika 库,pika 是一个用于与 RabbitMQ 消息队列进行交互的 Python 库
import pika
# 从 Django 的配置模块中导入 settings 对象,用于获取 Django 项目中的配置信息
from django.conf import settings

# 定义一个回调函数,当从 RabbitMQ 队列接收到消息时,pika 库会调用这个函数来处理消息
def callback(ch, method, properties, body):
    # ch 是通道对象,用于与 RabbitMQ 服务器进行交互
    # method 包含消息的元数据,如路由键、交换器等
    # properties 包含消息的属性,如优先级、内容类型等
    # body 是接收到的消息的实际内容,是字节类型,使用 decode() 方法将其转换为字符串
    print(f"Received message: {body.decode()}")

# 定义一个函数,用于从 RabbitMQ 队列中消费消息
def consume_messages():
    # 使用 pika 库创建一个到 RabbitMQ 服务器的阻塞连接
    # pika.URLParameters(settings.RABBITMQ_URL) 根据 Django 配置文件中的 RABBITMQ_URL 来解析连接参数
    # 例如 RABBITMQ_URL 可能是 'amqp://guest:guest@localhost:5672/'
    connection = pika.BlockingConnection(pika.URLParameters(settings.RABBITMQ_URL))
    # 从连接中创建一个通道,所有与消息队列的交互都通过通道进行
    channel = connection.channel()
    # 声明一个队列,如果该队列不存在则创建它
    # 这里声明的队列名为 'my_queue',确保在消费消息前队列已经存在
    channel.queue_declare(queue='my_queue')
    # 开始消费指定队列中的消息
    # queue='my_queue' 表示要消费的队列名称
    # on_message_callback=callback 表示当接收到消息时,调用 callback 函数进行处理
    # auto_ack=True 表示自动确认消息,即消息被消费后自动告知 RabbitMQ 服务器该消息已处理
    channel.basic_consume(queue='my_queue', on_message_callback=callback, auto_ack=True)
    # 打印提示信息,告知用户程序正在等待接收消息,并提示如何退出程序
    print('Waiting for messages. To exit press CTRL+C')
    # 开始进入消息消费循环,持续监听队列中的消息
    # 当有新消息到达时,会调用指定的回调函数进行处理
    channel.start_consuming()

# 主程序入口,当脚本作为主程序直接运行时执行以下代码
if __name__ == '__main__':
    # 调用 consume_messages 函数开始消费消息
    consume_messages()

此脚本定义了接收消息的回调函数,连接服务器并开始消费指定队列的消息。

结合Celery(推荐)

Celery是Django中常用的分布式任务队列框架,可简化消息队列使用:

  1. 安装pip install celery
  2. 配置:在Django项目中创建celery.py文件进行配置,例如:
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')

app = Celery('your_project')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

settings.py中添加Celery相关配置,如指定消息队列(以Redis为例):

CELERY_BROKER_URL ='redis://localhost:6379/0'
CELERY_RESULT_BACKEND ='redis://localhost:6379/0'
  1. 定义任务:在app目录下创建tasks.py,定义异步任务,如:
from celery import task

@task
def add(x, y):
    return x + y
  1. 调用任务:在视图函数等地方调度任务,如add.delay(4, 6)

通过消息队列,Django可实现异步处理耗时任务(如发送邮件、处理文件等),提升系统响应速度和性能,还能解耦系统组件,增强可扩展性和可靠性。

posted @ 2025-03-27 22:40  一只大学生  阅读(270)  评论(0)    收藏  举报