一、介绍
RabbitMQ,俗称“兔子MQ”(可见其轻巧,敏捷),是目前非常热门的一款开源消息中间件,不管 是互联网行业还是传统行业都广泛使用(最早是为了解决电信行业系统之间的可靠通信而设计)。
1. 高可靠性、易扩展、高可用、功能丰富等
2. 支持大多数(甚至冷门)的编程语言客户端。
3. RabbitMQ遵循AMQP协议,自身采用Erlang(一种由爱立信开发的通用面向并发编程的语 言)编写。
4. RabbitMQ也支持MQTT等其他协议。
RabbitMQ具有很强大的插件扩展能力,官方和社区提供了非常丰富的插件可供选择:
https://www.rabbitmq.com/community-plugins.html
二、整体逻辑架构
1、RabbitMQ Exchange类型
RabbitMQ常用的交换器类型有: fanout 、 direct 、 topic 、 headers 四种。
Fanout
fanout会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中,如图:
Direct
direct类型的交换器路由规则很简单,它会把消息路由到那些BindingKey和RoutingKey完全匹配的 队列中,如下图:
Topic
topic类型的交换器在direct匹配规则上进行了扩展,也是将消息路由到BindingKey和RoutingKey 相匹配的队列中,这里的匹配规则稍微不同,它约定: BindingKey和RoutingKey一样都是由"."分隔的字符串;BindingKey中可以存在两种特殊字符“*”和 “#”,用于模糊匹配,其中"*"用于匹配一个单词,"#"用于匹配多个单词(可以是0个)。
Headers
headers类型的交换器不依赖于路由键的匹配规则来路由信息,而是根据发送的消息内容中的 headers属性进行匹配。在绑定队列和交换器时指定一组键值对,当发送的消息到交换器时, RabbitMQ会获取到该消息的headers,对比其中的键值对是否完全匹配队列和交换器绑定时指定的键 值对,如果匹配,消息就会路由到该队列。headers类型的交换器性能很差,不实用。
2、RabbitMQ数据存储
RabbitMQ消息有两种类型: 1. 持久化消息和非持久化消息。 2. 这两种消息都会被写入磁盘。
持久化消息在到达队列时写入磁盘,同时会内存中保存一份备份,当内存吃紧时,消息从内存中清 除。这会提高一定的性能。
非持久化消息一般只存于内存中,当内存压力大时数据刷盘处理,以节省内存空间。
RabbitMQ存储层包含两个部分:队列索引和消息存储。
三、工作流程
1、生产者发送消息的流程
1)生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
2)生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
3)生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
4)生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来
5)生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息
6) 相应的交换器根据接收到的 routingKey 查找相匹配的队列。
7)如果找到,则将从生产者发送过来的消息存入相应的队列中。
8)如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
9)关闭信道。
10)关闭连接。
2、 消费者接收消息的过程
1) 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
2)消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及 做一些准备工作
3)等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
4)消费者确认( ack) 接收到的消息。
5)RabbitMQ 从队列中删除相应已经被确认的消息。
6)关闭信道。
7)关闭连接。