RabbitMQ基础知识

我们可以把 RabbitMQ 的运作看作是一个极其智能的物流分拣中心

1. 核心四大角色 🏗️

  • 生产者 (Producer) 🏭:消息的发送方。它只负责把消息发给交换机,并贴上一个"路由标签"(Routing Key)。

  • 交换机 (Exchange) 🚦:分拣中心的核心。它接收生产者的消息,并根据规则决定分发到哪个仓库(队列)。

  • 队列 (Queue) 📥:消息的缓冲区。消息在这里排队,直到被消费者取走。一个队列可以存放成千上万条消息。

  • 消费者 (Consumer) 👤:消息的接收方。它连接到队列,取走消息并执行具体的业务逻辑。

基础:简单的"生产者"与"消费者" 📮

这是最基础的模式:生产者将消息发送到队列,消费者从中取出。

生产者 (send.py):

复制代码
import pika

# 1. 建立连接
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 2. 声明队列(确保队列存在)
channel.queue_declare(queue='hello')

# 3. 发送消息
# exchange='' 表示使用默认交换机,它会将消息直接路由到 routing_key 指定的队列
channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello RabbitMQ!')

print(" [x] 已发送 'Hello RabbitMQ!'")
connection.close()

消费者 (receive.py):

复制代码
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

# 声明队列(防止消费者先启动导致找不到队列)
channel.queue_declare(queue='hello')

# 定义回调函数:当收到消息时执行的操作
def callback(ch, method, properties, body):
    print(f" [x] 收到消息: {body.decode()}")

# 告诉 RabbitMQ 使用 callback 来接收消息
channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)

print(' [*] 等待消息中... 按 CTRL+C 退出')
channel.start_consuming()

2. 它们是如何关联的?(Binding & Routing Key) 🔗

要让交换机知道把消息发给哪个队列,需要两个关键设置:

  • 绑定 (Binding):这是交换机和队列之间的"连接关系"。你可以理解为队列向交换机"订阅"了某种类型的消息。

  • 路由键 (Routing Key):生产者发消息时带上的"标签"。交换机会对比消息的标签和绑定的规则,匹配上了才投递。


3. 四大交换机模式(决定如何投递) 🛣️

这是 RabbitMQ 最灵活的地方,决定了消息的流向:

  1. Direct (直连模式) 🎯:精确匹配。路由键必须完全一致。例如:消息标签是 error,只有绑定了 error 的队列能收到。

  2. Fanout (广播模式) 📢:无视标签。交换机会把消息复制一份,发给所有绑定到它的队列。适合下单后同时通知库存、短信、积分系统。

  3. Topic (主题模式) 📝:模糊匹配。支持通配符(如 *.orange.*user.#)。适合按类别订阅消息,比如"所有关于用户的日志"。

  4. Headers (头模式) 🗄️:不根据标签,而是根据消息头里的属性进行匹配(较少使用)。

进阶:使用交换机 (Exchange) 实现广播模式 📢

在"广播模式"(Fanout)下,生产者不把消息发给特定队列,而是发给交换机,由交换机发给所有绑定的队列。

生产者 (emit_log.py):

Python

复制代码
# ... 建立连接代码同上 ...
# 声明一个名为 'logs' 的 fanout 交换机
channel.exchange_declare(exchange='logs', exchange_type='fanout')

channel.basic_publish(exchange='logs',
                      routing_key='',  # 广播模式下不需要指定具体队列名
                      body='系统日志:这是一条广播消息')

消费者 (receive_logs.py):

复制代码
# ... 建立连接和声明交换机代码同上 ...
# 1. 创建一个随机命名的临时队列,消费者断开后自动删除
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue

# 2. 将队列绑定到交换机上(这就是"订阅")
channel.queue_bind(exchange='logs', queue=queue_name)

# ... 之后的部分同基础消费者 ...

精准打击:主题模式 (Topic) 🧩

主题模式允许我们使用通配符(如 * 匹配一个单词,# 匹配多个单词)进行灵活路由。

生产者:

复制代码
# 声明 topic 类型的交换机
channel.exchange_declare(exchange='topic_logs', exchange_type='topic')

# 发送一条带标签的消息
routing_key = 'usd.stock.nyse' 
channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body='美股数据更新')

消费者(只订阅股票数据):

复制代码
# 绑定键使用通配符:匹配所有以 .stock. 结尾的中间部分
channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key='*.stock.#')

4. 核心优势:为什么要用它? 🛡️

  • 异步处理 (Asynchrony) ⏳:用户注册后,主程序直接返回成功,发邮件等耗时操作交给 RabbitMQ 慢慢处理,极大提升用户体验。

  • 应用解耦 (Decoupling) 🧱:订单系统不需要知道库存系统长什么样,只要把消息发给 RabbitMQ,库存系统自己去领任务即可。

  • 削峰填谷 (Peak Shaving) 🌊:秒杀活动流量暴增时,消息先堆积在队列里,后端服务器按自己的节奏慢慢处理,防止系统被瞬间冲垮。


5. 消息的安全性(不丢失的保障) 🔒

  • 持久化 (Persistence):把消息存入硬盘,即使 RabbitMQ 重启,消息也不会丢失。

  • 确认机制 (Ack) :消费者处理完消息后回复一个 ACK。如果消费者在处理时挂了,没有回复,RabbitMQ 会把这条消息重新发给别人,确保一定被处理。


相关推荐
南 阳2 小时前
Python从入门到精通day58
开发语言·python
weixin_433179332 小时前
Python - 调试
java·开发语言·python
代码探秘者2 小时前
【算法篇】6.分治
java·数据结构·后端·python·算法·排序算法
Elastic 中国社区官方博客2 小时前
我们如何修复 OpenTelemetry 中基于 head 的采样
大数据·开发语言·python·elasticsearch·搜索引擎
Jack N2 小时前
消息中间件RabbitMQ vs Kafka vs Pulsar 详细对比
分布式·kafka·rabbitmq
梦因you而美2 小时前
Python自动化复制Excel sheet表(openpyxl+win32com双方案,完美保留格式)
python·自动化·excel·win32com·openpyxl
迷藏4942 小时前
**基于Python与Neo4j的知识图谱构建实践:从数据到语义网络的跃迁**在人工智能与大数据深度融合
java·人工智能·python·neo4j
kcuwu.2 小时前
Anaconda创建虚拟环境及Pycharm关联(搭建ai智能体准备工作)
ide·python·pycharm
小陈工4 小时前
Python安全编程实践:常见漏洞与防护措施
运维·开发语言·人工智能·python·安全·django·开源