RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都表现不俗,也是目前社区活跃度较高的消息中间件之一。本文我们就来看看RabbitMQ很重要的核心的组件。
RabbitMQ是一个用Erlang语言开发的、实现了AMQP协议的消息中间件。
AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。
重头戏!很重要!
下图是RabbitMQ的结构模型,生产者发送消息给交换机,交换机根据路由规则,将不同的消息路由到不同的队列(什么是路由规则继续往下看),消费者订阅/监听队列,当有消息过来时,就立即消费。对着图,我们先来搞懂RabbitMQ中几个非常非常重要的概念。
> Broker
Broker简单理解就是RabbitMQ服务器,图中灰色的整个部分。后面说Broker说的就是RabbitMQ服务器。
> vHost 虚拟主机
每一个RabbitMQ服务器可以开设多个虚拟主机vhost(图中粉色的部分),或者说每一个Broker里可以开设多个vhost,每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的 "交换机exchange、绑定Binding、队列Queue",更重要的是每一个vhost拥有独立的权限机制,这样就能安全地使用一个RabbitMQ服务器来服务多个应用程序,其中每个vhost服务一个应用程序。
每一个RabbitMQ服务器都有一个默认的虚拟主机 "/",客户端连接RabbitMQ服务时须指定vHost,如果不指定默认连接的就是"/"。
> Exchange 交换机
交换机的作用就是根据路由规则,将消息转发到对应的队列上。
> Connection
我们知道无论是生产者还是消费者,都需要和 Broker 建立连接,这个连接就是Connection(看图),是一条 TCP 连接 ,一个生产者或一个消费者与 Broker 之间只有一个Connection,即只有一条TCP连接。
> ConnectionFactory
Connection工厂,负责创建和管理Connection的。
> Channel
信道是建立在真实的TCP连接内的虚拟连接(图中白色的channel)。AMQP的命令都是通过信道发送出去的,每条信道都会被指派一个唯一ID,不论是发布消息、订阅队列还是接收消息都是通过信道完成的。一个TCP连接下包含多个信道,实现共用TCP、减少TCP创建和销毁的开销。
> Routing key
Routing key是消息头的属性,生产者将消息发送到交换机时,会在消息头上携带一个 key,这个 key就是routing key,来指定这个消息的路由规则。
> Binding
绑定,可以理解成一个动词,它的作用就是把exchange和queue按照路由规则绑定起来。
> Binding key
在绑定Exchange与Queue时,一般会指定一个binding key,生产者将消息发送给Exchange时,消息头上会携带一个routing key,当binding key与routing key相匹配时,消息将会被路由到对应的Queue中。
如果上面的各个核心概念看完了还有点迷糊,没关系,继续往下看。
首先,生产者发送消息到交换机,消息头上携带一个routing key,通过routing key,交换机就知道该把消息发到哪个队列,随后交换机把消息发送到相应的队列中,再由队列将消息发送给消费者,消费者监听(订阅)某些队列,当有消息过来时,就立即处理消息。
上面我们说了,生产者发送消息给交换机,消息头上会携带一个routing key,通过routing key,交换机就知道该把消息分发到哪个队列,那么交换机根据routing key如何判断这个消息应该路由到哪个队列呢?或者说交换机的路由规则是什么样的呢?
※ RabbitMQ 的交换机有四种类型:fanout、direct、topic、headers。
> fanout
fanout 交换机就跟广播一样,对消息不作选择地分发给所有绑定的队列。
> direct
在 direct 模式里,交换机和队列之间绑定了一个 key(这个key就是Binding key),只有消息的 Routing key 与Binding key 相同时,交换机才会把消息发给该队列。
如上图,消息的Routing key 为 orange 时,消息将进入队列 Q1,Routing key 为 black 或green 时,消息将进入队列Q2。若消息的 key 是其他字符串,被交换机直接遗弃。
同时,交换机也支持多重绑定。不同的队列可以用相同的Binding key与同一交换机绑定。如上图,当消息的Routing key为black时,消息将进入 Q1 和 Q2。
> topic
topic模式即主题模式,通过模式匹配来路由到队列。topic 模式的Routing key必须具有固定的格式:以 . 间隔的一串单词,
比如:quick.orange.rabbit,Routing key 最多不能超过255byte。
交换机和队列的Binding key用通配符来表示,有两种语法:
* 可以替代一个单词;
# 可以替代 0 或多个单词;
上图中,Q1与交换机的Binding kye为"*.orange.*",当消息的Routing key为三个单词,且中间的单词为 orange 时,消息将进入 Q1。Q2 与 exchange的Binding key 为 "rabbit.#",当消息的Routing key以 rabbit 开头时,消息将进入 Q2 。
> headers
不常用,headers交换机是通过Headers头部来将消息映射到队列的,Headers头部携带一个Hash结构,Hash结构中要求携带一个键"x-match",这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了。相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串String类型。
> 默认交换机
default Exchange,默认交换机的名字是空字符串。
如果在发送消息时不指定交换机的名称,那么就会发到"默认交换机"上。默认的Exchange不进行Binding操作,任何发送到该Exchange的消息都会被转发到"Queue名字和Routing key相同的队列"中,如果vhost中不存在和Routing key同名的队列,则该消息会被抛弃。
要学习RabbitMQ,先掌握RabbitMQ的结构模型很重要,以及它们之间的工作模式,希望多加揣摩理解。