image.png

1. 消息基于什么传输?

由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制。

2. 消息怎么路由?

从概念上来说,消息路由必须有三部分:交换器路由绑定
生产者把消息发布到交换器上;绑定决定了消息如何路由到特定的队列;消息最终到达队列,并被消费者接收。
消息发布到交换器时,消息将拥有一个路由键(routing key),在消息创建时设定。通过队列路由键,可以把队列绑定到交换器上。
消息到达交换器后,RabbitMQ会将消息的路由键与队列的路由键进行匹配(针对不同的交换器有不同的路由规则)。如果能够匹配到队列,则消息会投递到相应队列中;如果不能匹配到任何队列,消息将进入 “黑洞”。
常用的交换器主要分为一下三种:

  • direct:如果路由键完全匹配,消息就被投递到相应的队列
  • fanout:如果交换器收到消息,将会广播到所有绑定的队列上
  • topic:可以使来自不同源头的消息能够到达同一个队列。使用topic交换器时,可以使用通配符。
    比如:“*” 匹配特定位置的任意文本, “.” 把路由键分为了几部分,“#” 匹配所有规则等。特别注意:发往topic交换器的消息不能随意的设置选择键(routing_key),必须是由”.”隔开的一系列的标识符组成

3.如何保证RabbitMQ消息的可靠传输?

生产者丢失消息:RabbitMQ提供transaction机制confirm模式来确保生产者不丢消息;

  • transaction机制:发送消息前,开启事务,然后发送消息,如果发送过程中出现什么异常,事务就会回滚,如果发送成功则提交事。
  • confirm模式(用的居多):一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后; RabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;

如果RabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

消息队列丢数据: 消息持久化,处理消息队列丢数据的情况,一般是开启持久化磁盘的配置

消费者丢失消息: 消费者丢数据一般是因为采用了自动确认消息模式,改为手动确认消息 ,消费者在收到消息之后,处理消息之前,会自动回复RabbitMQ已收到消息; 如果这时处理消息失败,就会丢失该消息; 解决方案:处理消息成功后,手动回复确认消息。

4. 如何解决丢数据的问题?

image.png
image.png

7.保证可靠消息——防止消息丢失

手动ACK!!!消费成功才回复ACK
image.png

image.png

image.png
image.png

8.如何保证消息顺序执行

2.出现顺序错乱的场景


①一个queue,有多个consumer去消费,这样就会造成顺序的错误,consumer从MQ里面读取数据是有序的,但是每个consumer的执行时间是不固定的,无法保证先读到消息的consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。

②一个queue对应一个consumer,但是consumer里面进行了多线程消费,这样也会造成消息消费顺序错误。

3.保证消息的消费顺序

①拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点;这样也会造成吞吐量下降,可以在消费者内部采用多线程的方式取消费。
②或者就一个queue但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理
📝RabbitMQ - 图9