RabbitMQ 笔记
先看一下官网的一张图片 ,基本就可以了解到整个流程
基本为 Publisher 发送消息到 Exchange,由 Exchange 根据规则发送到特定的一个或多个 Queue,最后由 Consumer 从 Queue 中得到消息。
下面对流程中的各个部分进行一一介绍:
Exchange - 交换机
交换机拿到消息后,发送给队列,其具体规则有交换机类型和 bindings(绑定) 的规则所决定。
系统初始已经存在了各类交换机可以直接使用,默认名称等信息如下表:
交换机类型 | 默认名称 |
---|---|
Direct exchange - 直连交换机 | 空字符串 或 amq.direct |
Fanout exchange - 扇型交换机 | amq.fanout |
Topic exchange - 主题交换机 | amq.topic |
Headers exchange - 头交换机 | amq.headers |
直连交换机
直连型交换机是根据消息携带的路由键(routing key)将消息发送给指定队列的 :
-
将一个队列绑定到某个直连交换机上,同时赋予该绑定一个路由键(routing key)
-
当一个携带着路由键为 R 的消息被发送给直连交换机时,交换机会它传递给绑定值同样为 R 的队列
import pika
# 只有 A 队列能收到消息 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.exchange_declare(exchange='first', exchange_type='direct') channel.queue_declare(queue='A') channel.queue_declare(queue='B') channel.queue_bind(exchange='first', queue='A', routing_key='a') channel.queue_bind(exchange='first', queue='B', routing_key='b') channel.basic_publish(exchange='first', routing_key='a', body='Hello World!')
扇型交换机
扇型交换机将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键
import pika # 绑定的 A、B 队列都能收到消息 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.exchange_declare(exchange='first', exchange_type='fanout') channel.queue_declare(queue='A') channel.queue_declare(queue='B') channel.queue_declare(queue='C') channel.queue_bind(exchange='first', queue='A') channel.queue_bind(exchange='first', queue='B') channel.basic_publish(exchange='first', routing_key='', body='Hello World!')
主题交换机
主题交换机通过对消息的路由键和队列到交换机的绑定模式之间的匹配,将消息路由给一个或多个队列
import pika # A、B 队列能收到消息,C 收不到消息 —— * 表示一个词,# 表示0个或多个词 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.exchange_declare(exchange='first', exchange_type='topic') channel.queue_declare(queue='A') channel.queue_declare(queue='B') channel.queue_declare(queue='C') channel.queue_bind(exchange='first', queue='A', routing_key='a.*.*') channel.queue_bind(exchange='first', queue='B', routing_key='a.#') channel.queue_bind(exchange='first', queue='C', routing_key='a.*') channel.basic_publish(exchange='first', routing_key='a.b.c', body='Hello World!')
头交换机
头交换机使用多个消息属性来代替路由键建立路由规则,通过判断消息头的值能否与指定的绑定相匹配来确立路由规则
import pika # A 队列能收到消息, B 不能收到消息 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.exchange_declare(exchange='first', exchange_type='headers') channel.queue_declare(queue='A') channel.queue_declare(queue='B') channel.queue_bind(exchange='first', queue='A', arguments={'a': '1'}) channel.queue_bind(exchange='first', queue='B', arguments={'b': '2', 'c': 3}) channel.basic_publish(exchange='first', routing_key='', properties=pika.BasicProperties(headers = {'a': '1', 'b': '2'},), body='Hello World!')
Queue - 队列
队列名称
可以指定,如果传递空字符串会自动生成队列名称,并且在同一个通道(channel)的后续方法中,可以使用空字符串表示之前生成的队列名称。
以 amq. 开头的队列名称为预留名称,不能手动声明
队列持久化
可以选择是否将队列持久化到磁盘(不会持久化队列中的消息)
绑定
绑定是交换机将消息路由给队列所需遵循的规则。
可以将一个消息队列(可以设置一个可选的路由键)绑定到交换机
Channel - 通道
可以把通道理解成共享一个 TCP 连接的多个轻量化连接,可以在需要多个连接时,不需开启多个 TCP 连接从而节省资源等
Vhost - 虚拟主机
为了在一个单独的代理上实现多个隔离的环境(用户、用户组、交换机、队列等),提出了虚拟主机的概念
参考资料:RabbitMQ使用参考