RabbitMQ消息传递流程

两个新名词

本篇文章以上篇文章《Rabbit的基础概念》为基础,且在上篇文章的前提下又引入了两个新的概念:

连接( Connection)

我们知道绝大部分的通信都是基于网络协议的,其中TCP协议就是广为人知的一种协议,在RabbitMQ中,生产者和消费者与RabbitMQ的通信就是基于TCP连接的。不过呢我们知道TCP连接的创建和销毁在高并发场景下对于操作系统来说都是特别昂贵的开销,所以RabbitMQ又引入了信道的概念

信道(Channel)

信道是一个类似于NIO(一种TCP多路复用技术)的技术
在RabbitMQ中每个生产者、消费者线程各把持一个信道,多个信道复用了同一个TCP 连接。当每个信道的流量不是很大时,复用单连接可以在产生性能瓶颈的情况下有效地节 TCP 连接资源。当信道本身的流量很大时,就会开辟多连接,将这些信道均摊到这些连接中

消息流转过程

还是先看一下上篇文章的那副图
1

生产者消息投递过程
  1. 生产者连接到Broker 建立一个连接,然后开启一个信道
  2. 接着生产者声明一个交换器 ,并设置相关属性,比如交换机类型、是否持久化、是否自动删除、是否内置等
  3. 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除、消息最大过期时间、消息最大长度、消息最大字节数等
  4. 生产者通过路由键将交换器和队列绑定起来
  5. 生产者发送消息至Broker ,发送的消息包含消息体和含有路由键、交换器、优先级、是否持久化、过期时间、延时时间等信息的标签
  6. 相应的交换器根据接收到的路由键查找相匹配的队列如果找到 ,则将从生产者发送过来的消息存入相应的队列中
  7. 如果没有找到 ,则根据生产者配置的属性选择丢弃还是回退给生产者
  8. 关闭信道
  9. 关闭连接
消费者消费消息过程
  1. 消费者连接到Broker ,建立一个连接,开启一个信道
  2. 消费者向 RabbitMQ Broker 请求消费相应队列中的消息,在这个过程中可能会设置消费者标签、是否自动确认、是否排他等
  3. 等待 RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
  4. 消费者确认接收到的消息
  5. RabbitMQ从队列中删除相应己经被确认的消息
  6. 关闭信道
  7. 关闭连接
涉及名词解释

在上方的消息流转过程中涉及了以下几个名词

是否持久化

将数据持久化到磁盘中

是否自动删除

当一个队列或交换机的所有消费者都与之断开连接时则这个队列或交换机就会自动删除

是否内置

客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式

是否排他

如果一个队列被声明为排他队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意的是:
排他队列是基于连接可见的,同一个连接的不同信道是可以同时访问同一连接创建的排他队列; "首次"是指如果一个连接己经声明了排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同:即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列适用于一个客户端同时发送和读取消息的应用场景。

自动确认

消费者在订阅队列时,可以指定 autoAck 参数,当 autoAck 等于 false时, RabbitMQ会等待消费者显式地回复确认信号后才从内存(或者磁盘)中移去消息(实质上是先打上删除标记,之后再删除)
当 autoAck 等于 true 时, RabbitMQ 会自动把发送出去的消息置为确认,然后从内存(或者磁盘)中删除,而不管消费者是否真正地消费到了这些消息
采用消息确认机制后,只要设置 autoAck 参数为 false ,消费者就有足够的时间处理消息,不用担心处理消息过程中消费者进程挂掉后消息丢失的问题。因为 RabbitMQ 会一直等待持有消息直到消费者显式确认收到消息

推荐阅读

  1. SpringCloud学习系列汇总
  2. 为什么一线大厂面试必问redis,有啥好问的?
  3. 多线程面试必备基础知识汇总
  4. Java集合源码分析汇总-JDK1.8
  5. Linux常用命令速查-汇总篇
  6. JVM系列文章汇总
  7. MySQL系列文章汇总

博客所有文章首发于公众号《Java学习录》转载请保留
扫码关注公众号即可领取2000GJava学习资源

1

猜你喜欢

转载自blog.csdn.net/myFirstCN/article/details/93501215