RabbitMQ入门
1.RabbitMQ基本组成
RabbitMQ有一些基本的组成单元:
Producer
:消息的生产者Consumer
:消息的消费者Broker
:RabbitMQ的服务节点。形象一点说就是一个Broker等同于一台RabbitMQ服务器,可以接收Producer的消息,并存储消息与队列中,最终将消息发送给ConsumerQueue
:存储消息- 注意,RabbitMQ的消息只能存储在Queue中,而Kafka将消息存储于topic的逻辑层面,Kafka的队列逻辑只是topic实际存储文件上的位移
- 多个消费者订阅同一个队列中的消息时,队列中的消息只能被一个消费者处理(即RabbitMQ不支持队列层面上的广播)
Exchange
:交换器,位于生产者和队列中间。实际上,所有Producer生产的消息,并不是直接被Producer写入队列,而是由Producer将消息交给Exchange,再由Exchange决定要将消息写入哪个队列中。这个写入消息的过程,也可以叫做"路由"Routing Key
:路由键。上面说Exchange将消息写入Queue的过程就是路由,那么对于一个Exchange来说,RabbitMQ中有很多个Queue,Exchange可能需要具备区分每一个Queue的能力。- 举个例子,Producer将消息发给Exchange的时候,一般要指定一个Routing Key,Exchange会使用该Routing Key和每个队列的Binding Key匹配上了,如果相同,就将消息写入对应的队列
- 在某些场景下,Routing Key其实和Binding Key是相同的
2.Exchange类型
fanout
:将所有发送到该Exchange的消息路由到所有与该Exchange绑定的Queue上direct
:将所有发送到该Exchange的消息路由到RoutingKey和BindingKey完全匹配的Queue上topic
:因为RoutingKey和BindingKey都是用.
分隔的字符串(类似于java的包名),topic类型的Exchange支持使用*
#
作为通配符来制定模糊匹配RoutingKey、BindingKey的规则header
:不依赖RoutingKey来路由消息,而是根据发送的消息头(header属性)进行匹配
3.生产消息流程
消息生产者发送消息流程如下:
- Producer连接到RabbitMQ Broker,建立连接(Connection),开启信道(Channel)
- Producer声明一个交换器Exchange并设置相关属性
- Producer声明一个队列Queue并设置相关属性
- Producer通过路由键RoutingKey将Exchange和Queue绑定起来
- Producer发送消息到Broker
- Broker的Exchange根据路由键查找匹配的队列
- 如果找到,Exchange将消息存入队列中
- 如果没找到,丢弃或者退回消息
- 关闭信道、连接
4.消费消息流程
消费者消费消息的流程如下:
- Consumer连接到RabbitMQ Broker,建立连接(Connection),开启信道(Channel)
- Consumer向Broker请求消费某个队列的消息,并等待Broker发送消息
- Consumer接收消息,并返回确认信息ack
- RabbitMQ从队列中删除已经被Consumer确认的消息
- 关闭信道、连接
5.信道Channel
其实只要一个生产者和Broker建立了Connection就能够实现通信,一个Connection对应一条TCP连接。但是通常情况下,生产者并不需要一直向向Broker发送消息,这就会降低Connection的使用效率。
因此,RabbitMQ使用了多路复用的概念,类似于Java IO中的selector模型。来自不同生产者(也可以是相同生产者)的线程复用一个Connection,每个生产线程和Connection之间建立一个逻辑连接就是Channel。这样,能够大大降低Connection(TCP连接)的连接数量
6.AMQP协议
AMQP协议,全称是Advanced Message Queuing Protocol(高级消息队列协议)。RabbitMQ可以看做是AMQP协议的落地实现。
AMQP协议模型和RabbitMQ是一致的:
- 生产者将消息发送给交换器
- 交换器和队列绑定
- 生产者的消息中携带的路由键如果和绑定时的绑定键匹配时,消息就会被存入相应的队列中
- 消费者可以订阅队列来获取消息