RabbitMQ原理

1 RabbitMQ原理

1.1 RabbitMQ原理图

在这里插入图片描述
在这里插入图片描述

1.2 原理讲解

1.2.1 Message消息

消息是不具名的, 它由消息头消息体组成。消息体是不透明的,而消息头则由一系列可选属性组成,这些属性包括:routing-key(路由键)、priority(相对于其他消息的优先权)、 delivery-mode(指出消息可能持久性存储)等。

1.2.2 Publisher消息生产者

消息生产者,是一个向交换器发布消息的客户端应用程序。

1.2.3 Consumer消息消费者

表示一个从消息队列中取得消息的客户端应用程序。

1.2.4 Exchange交换器

用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
三种常用的交换器类型:

  • direct(发布与订阅 完全匹配)
  • fanout(广播)
  • topic(主题, 规则匹配)

1.2.5 Binding绑定

用于消息队列交换器之间的关联。 一个绑定就是基于路由键将交换器和消息
队列连接起来的路由规则, 所以可以将交换器理解成一个由绑定构成的路由表

1.2.6 Queue消息队列

用来保存消息直到发送给消费者。 它是消息的容器, 也是消息的终点。 一个消息可投入一个或多个队列。 消息一直在队列里面, 等待消费者链接到这个队列将其取走。

1.2.7 Routing-key路由键

RabbitMQ决定消息该投递到哪个队列的规则。队列通过路由键绑定到交换器。
消息发送到MQ服务器时,消息将拥有一个路由键, 即便是空的,RabbitMQ也会将其和绑定使用的路由键进行匹配。
如果相匹配, 消息将会投递到该队列。
如果不匹配, 消息将会进入黑洞。

1.2.8 Connection链接

rabbit服务器和服务建立的TCP链接。

1.2.9 Channel信道

  • Channel中文叫做信道, 是 TCP 里面的虚拟链接。 例如: 电缆相当于TCP, 信道是一个独立光纤束, 一条 TCP 连接上创建多条信道是没有问题的。
  • TCP 一旦打开, 就会创建AMQP信道。
  • 无论是发布消息接收消息订阅队列, 这些动作都是通过信道完成的。

1.2.10 Virtual Host虚拟主机

表示一批交换器消息队列相关对象
虚拟主机是共享相同的身份认证加密环境的独立服务器域。 每个vhost本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列、 交换器、 绑定和权限机制。
vhostAMQP概念的基础, 必须在链接时指定,RabbitMQ默认的vhost/

1.2.11 Borker服务器实体

表示消息队列服务器实体

1.2.12 交换器和队列的关系

交换器是通过路由键队列绑定在一起的, 如果消息拥有的路由键跟队列和交换器的
路由键匹配, 那么消息就会被路由到该绑定的队列中。
也就是说, 消息到队列的过程中, 消息首先会经过交换器, 接下来交换器在通过路由
键匹配分发消息到具体的队列中。
路由键可以理解为匹配的规则。

1.2.13 RabbitMQ为什么需要信道,为什么不是TCP直接通信

  1. TCP的创建和销毁开销特别大。 创建需要3次握手, 销毁需要4次挥手。
  2. 如果不用信道, 那应用程序就会以TCP链接Rabbit, 高峰时每秒成千上万条链接会造成资源巨大的浪费,而且操作系统每秒处理 TCP 链接数也是有限制的, 必定造成性能瓶颈。
  3. 信道的原理是一条线程一条通道,多条线程多条通道同用一条TCP链接。一条TCP链接可以容纳无限的信道, 即使每秒成千上万的请求也不会成为性能的瓶颈。

1.3 RabbitMQ中的消息确认ACK机制

1.3.1 消息确认ACK理解

如果在处理消息的过程中,消费者的服务器在处理消息时出现异常,那可能这条正在处理的消息就没有完成消息消费,数据就会丢失,为了确保数据不丢失,RabbitMQ支持消息确认-ACK

1.3.2 ACK的消息确认机制

ACK机制是消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQRabbitMQ收到反馈后才将此消息从队列中删除

  1. 如果一个消费者在处理消息出现了网络不稳定、服务器异常等现象,那么就不会有ACK反馈,RabbitMQ会认为这个消息没有正常消费,会将消息重新放入队列中`
  2. 如果在集群情况下,RabbitMQ会立即将这个消息推送给这个在线的其他消费者。这种机制保证了在消费者服务端故障的时候,不丢失任何消息和任务
  3. 消息永远不会从RabbitMQ中删除:只有当消费者正确发送ACK反馈,RabbitMQ确认收到后,消息才会从RabbitMQ服务器的数据中删除
  4. 消息的ACK确认机制默认是打开的

1.3.3 ACK机制的注意

如果忘记了ACK,那么后果很严重。当consumer退出时,Message会一直重新分发。
然后RabbitMQ占用越来越多的内存,由于RabbitMQ会长时间运行,因此内存泄漏是致命的

1.3.4 接受方出现异常

因为接受方consumer出现异常,消息会放到队列里面,而导致这个消息不会删除而一直都是那个消息重复发送,为了预防网络波动的异常,而不得不使用原来的消息,就应该开启重试机制,而应该使用如下配置。

#开启重试
spring.rabbitmq.listener.simple.retry.enabled=true
#重试次数, 默认为 3 次
spring.rabbitmq.listener.simple.retry.max-attempts=3
发布了334 篇原创文章 · 获赞 186 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/u012060033/article/details/104228508