前言
RabbitMQ整体上是一个生产者与消费者模型,主要负责接收,存储和转发消息。RabbitMQ整体模型架构(如下图)。
生产者和消费者
- Producer:生产者,消息投递一方。生产者生产消息,然后发布到RabbitMQ。消息一般包含2个部分:消息体(payload)和标签(Label),生产者把消息交由RabbitMQ,RabbitMQ之后会根据标签把消息发送给感兴趣的消费者。
- Consumer:消费者,消息接收一方。消费者连接到RabbitMQ服务器,并订阅到队列上。当消费者消费一条消息时,只消费消息的消息体(payload)。消息路由过程中,消息标签丢弃,存入队列中的消息只有消息体。
- Broker:消息中间件的服务节点。对于RabbitMQ来说,一个RabbitMQ Broker可以简单看作一个RabbitMQ服务节点或则RabbitMQ服务实例。一般情况下一个RabbitMQ Broker看作一台RabbitMQ服务器。
队列
Queue:队列。用于储存消息,RabbitMQ中消息都只能储存在队列中。
交换器、路由键、绑定
- Exchange:交换器。发送消息的AMQP实体。交换器拿到一个消息之后将它路由给一个或零个队列。它使用哪种路由算法是由交换机类型和被称作绑定(Binding)的规则所决定的。RabbitMQ有四种类型。
- RoutingKey:路由键。生产者将消息发送给交换器。一般会指定一个RoutingKey,用来指定这个消息的路由规则,而这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终失效。
- Binding:绑定。绑定(Binding)是交换机(Exchange)将消息(Message)路由给队列(Queue)所需遵循的规则。
交换器类型
RabbitMQ常用的交换器类型有fanout、direct、topic、headers这四种
- fanout:会把所有发送到交换器的消息路由到所有与该交换器绑定的队列中。
- direct:会把消息路由到那些BindKey和RoutingKey完全匹配的队列中。
- topic:与direct类型的交换器相似,也是将消息路由到BindingKey和RoutingKey相匹配的队列中,但匹配规则不同:
- RoutingKey为一个点号"."分割的字符串(被点号"."分割开的每一段都是一段独立字符串称为一个单词),如"node1.rabbitmq.client"、"node2.rabbitmq.client"。
- BindingKey与RoutingKey一样也是点号"."分割的字符串。
- BandingKey中可以存在两种特殊的字符串"*"和"#",用于模糊匹配,"*"匹配一个单词,"#"匹配零个或则多个单词。
- 列举一些例子
- 路由键为"node.orange.rabbitmq"的消息会同时路由到Q1和Q2;
- 路由键为"abc.orange.def"的消息会路由到Q1;
- 路由键为"abc.def.rabbitmq"的消息会被路由到Q2;
- 路由键为"lazy.abc.def"的消息会被路由到Q2;
- 路由键为"abc.def.ghi"的消息会被丢弃;
- headers:不依赖于路由键的匹配规则来的路有消息,而是根据发送的消息内容中的headers属性进行匹配。在绑定队列和交换器时制定一组键值对,发送消息到交换器时,RabbitMQ会获取到该消息的headers,对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配会路由到该队列,否则不会路由到该队列。
RabbitMQ运转流程
最初状态下,生产者发送消息
- 生产者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)。
- 生产者声明一个交换器,并设置相关属性,比如交换机类型、是否持久化等。
- 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等。
- 生产者通过路由键将交换器和队列绑定起来。
- 生产者发送消息至 RabbitMQ Broker,其中包含路由键、交换器等信息。
- 相应的交换器根据收到的路由键查找相匹配的队列。
- 如果找到,则将从生产者发送过来的消息存入相应的队列中。
- 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者。
- 关闭信道。
- 关闭连接。
消费者接收消息过程
- 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
- 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作。
- 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
- 消费者确认( ack) 接收到的消息。
- RabbitMQ 从队列中删除相应己经被确认的消息。
- 关闭信道。
- 关闭连接。
连接、信道
无论生产者还是消费者,都需要和RabbitMQ Broker建立连接,这个连接就是一条TCP连接,也就是连接(Connection),一旦TCP建立连接,客户端紧接着可以创建一个AMQP信道(Channel),每个信道都会被指派一个唯一的ID,信道是建立在Connection之上的虚拟连接,RabbitMQ处理每一条AMQP指令都是通过信道完成的。
参考:《RabbitMQ实战指南》