RabbitMQ架构了解

一,RabbitMQ工作流程

生产者发送消息的流程:

  • 1. 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
  • 2. 生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
  • 3. 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
  • 4. 生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来
  • 5. 生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息
  • 6. 相应的交换器根据接收到的 routingKey 查找相匹配的队列。
  • 7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。
  • 8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
  • 9. 关闭信道。
  • 10. 关闭连接。

消息接收消息的流程:

  • 1. 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
  • 2. 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及 做一些准备工作
  • 3. 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
  • 4. 消费者确认( ack) 接收到的消息。
  • 5. RabbitMQ 从队列中删除相应己经被确认的消息。
  • 6. 关闭信道。
  • 7. 关闭连接。 

Connection 和Channel关系:

        生产者和消费者,需要与RabbitMQ Broker 建立TCP连接,也就是Connection 。一旦TCP 连接建 立起来,客户端紧接着创建一个AMQP 信道(Channel),每个信道都会被指派一个唯一的ID。信道是建立在Connection 之上的虚拟连接, RabbitMQ 处理的每条AMQP 指令都是通过信道完成的。 

 为什么不直接使用TCP连接,而是使用信道?

  • RabbitMQ 采用类似NIO的做法,复用TCP 连接,减少性能开销,便于管理。 当每个信道的流量不是很大时,复用单一的Connection 可以在产生性能瓶颈的情况下有效地节省 TCP 连接资源。
  • 当信道本身的流量很大时,一个Connection 就会产生性能瓶颈,流量被限制。需要建立多个 Connection ,分摊信道。具体的调优看业务需要。

二,RabbitMQ工作模式 

1,工作队列(Work Queue)

生产者发消息使用Direct交换器,启动多个消费者实例来消费消息,每个消费者仅消费部分信息,可达到负载均衡的 效果。

2,发布订阅模式 

使用fanout类型交换器,routingKey忽略。每个消费者定义生成一个队列并绑定到同一个 Exchange,每个消费者都可以消费到完整的消息,消息广播给所有订阅该消息的消费者。

<在RabbitMQ中,生产者不是将消息直接发送给消息队列,实际上生产者根本不知道一个消息被发 送到哪个队列。>

生产者将消息发送给交换器。交换器非常简单,从生产者接收消息,将消息推送给消息队列。交换 器必须清楚地知道要怎么处理接收到的消息。应该是追加到一个指定的队列,还是追加到多个队列,还是丢弃。规则就是交换器类型。

3,路由模式

使用 direct 类型的Exchange,发N条消费并使用不同的 routingKey ,消费者定义队列并将队列、 routingKey 、Exchange绑定。此时使用 direct 模式Exchagne必须要 routingKey 完全匹配的 情况下消息才会转发到对应的队列中被消费。

direct 交换器的路由算法很简单:只要消息的 routingKey 和队列的 bindingKey 对应,消息就可以推送给该队列,同一个routingKey的消息也可以通过多重绑定发送到不同的队列中去缓解队列调度压力。

 

 4,主题模式

使用 topic 类型的交换器,队列绑定到交换器、 bindingKey 时使用通配符,交换器将消息路由转 发到具体队列时会根据消息 routingKey 模糊匹配,比较灵活。

topic 类型的交换器, routingKey 就不能随便写了,它必须得是点分单词。单词可以随便 写,生产中一般使用消息的特征。如:“stock.usd.nyse”,“nyse.vmw”,“quick.orange.rabbit”等。该 点分单词字符串最长255字节。

bindingKey 也必须是这种形式。 topic 类型的交换器背后原理跟 direct 类型的类似:只要队列的 bindingKey 的值与消息的 routingKey 匹配,队列就可以收到该消息。

有两个不同:

  • 1. * (star)匹配一个单词
  • 2. # 匹配0到多个单词

 

 

Guess you like

Origin blog.csdn.net/qq_42773863/article/details/121505042