Rabbitmq

Posted by Wh0ami-hy on September 11, 2023

1. RabbitMQ 是什么

消息队列就是一个使用队列来通信的组件

RabbitMQ 是一个在 AMQP(Advanced Message Queuing Protocol )基础上实现的,可复用的企业消息系统。它可以用于大型软件系统各个模块之间的高效通信,支持高并发,支持可扩展。它支持 AJAX,持久化,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

2. 应用场景

  1. 异步通信:RabbitMQ 可以用作分布式系统之间的异步通信机制。当一个系统需要向另一个系统发送消息并且不需要等待即时响应时,可以使用 RabbitMQ 来发送消息并继续处理其他任务。

  2. 解耦系统组件:在大型分布式系统中,各个组件之间可能存在依赖关系。通过使用 RabbitMQ,可以将这些组件解耦,使它们能够独立地进行工作。一个组件可以将消息发送到 RabbitMQ,而不需要知道哪些组件将接收这些消息。

  3. 负载均衡:当多个消费者订阅同一个队列时,RabbitMQ 可以根据一定的策略将消息均匀地分发给这些消费者,从而实现负载均衡。这对于需要处理大量消息的应用程序特别有用,可以提高系统的吞吐量和并发性能。

  4. 日志收集和分发:RabbitMQ 可以用作日志消息的收集和分发中心。应用程序可以将日志消息发送到 RabbitMQ,然后由日志处理系统订阅和处理这些消息。这种方式可以实现集中式的日志管理和分发,方便进行日志分析和故障排查。

  5. 任务队列:RabbitMQ 可以用作任务队列,用于处理异步任务。应用程序可以将需要处理的任务封装成消息发送到队列中,然后由消费者进行处理。这种方式可以提高任务的并发处理能力,同时保证任务的可靠性和可恢复性。

  6. 分布式系统集成:当多个分布式系统之间需要进行数据交换和通信时,RabbitMQ 可以作为它们之间的消息中间件。通过定义消息的格式和协议,各个系统可以通过 RabbitMQ 进行数据的传递和交换,实现系统之间的集成和协作。

3. RabbitMQ 核心概念

RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。

3.1. Producer(生产者) 和 Consumer(消费者)

消息一般由 2 部分组成:消息头(或者说是标签 Label)和 消息体。消息体也可以称为 payLoad ,消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括 routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

3.2. Exchange(交换器)

Exchange(交换器) 用来接收生产者发送的消息并将这些消息路由给服务器中的队列中,如果路由不到,或许会返回给 Producer(生产者) ,或许会被直接丢弃掉。 RabbitMQ 的 Exchange(交换器) 有 4 种类型,不同的类型对应着不同的路由策略direct(默认)fanouttopicheaders,不同类型的 Exchange 转发消息的策略有所区别。

RabbitMQ 中通过 Binding(绑定)Exchange(交换器)Queue(消息队列) 关联起来,在绑定的时候一般会指定一个 BindingKey(绑定建),这样 RabbitMQ 就知道如何正确将消息路由到队列了。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。Exchange 和 Queue 的绑定可以是多对多的关系

3.3. Queue(消息队列)

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

多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理,这样避免消息被重复消费

RabbitMQ 不支持队列层面的广播消费,如果有广播消费的需求,需要在其上进行二次开发,这样会很麻烦,不建议这样做。

3.4. Broker(消息中间件的服务节点)

大多数情况下可以将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器或者 RabbitMQ 服务实例

4. AMQP

AMQP是高级消息队列协议(Advanced Message Queuing Protocol)的缩写。它是一种开放的标准应用层协议,用于不同软件系统之间可靠和高效的通信。AMQP使应用程序和服务之间可以交换消息,提供了一种标准化的方式来确保消息的传递、路由和排队。

5. RabbitMQ 的工作模式

  • 简单模式
  • work 工作模式
  • pub/sub 发布订阅模式
  • Routing 路由模式
  • Topic 主题模式

6. RabbitMQ 消息的传输

由于 TCP 链接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈,所以 RabbitMQ 使用信道的方式来传输数据。信道(Channel)是生产者、消费者与 RabbitMQ 通信的渠道,信道是建立在 TCP 链接上的虚拟链接,且每条 TCP 链接上的信道数量没有限制。就是说 RabbitMQ 在一条 TCP 链接上建立成百上千个信道来达到多个线程处理,这个 TCP 被多个线程共享,每个信道在 RabbitMQ 都有唯一的 ID,保证了信道私有性,每个信道对应一个线程使用

7. 如何保证消息的可靠性

消息到 MQ 的过程中搞丢,MQ 自己搞丢,MQ 到消费过程中搞丢。

  • 生产者到 RabbitMQ:事务机制和 Confirm 机制,注意:事务机制和 Confirm 机制是互斥的,两者不能共存,会导致 RabbitMQ 报错。
  • RabbitMQ 自身:持久化、集群、普通模式、镜像模式。
  • RabbitMQ 到消费者:basicAck 机制、死信队列、消息补偿机制

8. 如何保证 RabbitMQ 消息的顺序性

一个 queue(消息队列)但是对应一个 consumer(消费者),然后这个 consumer(消费者)内部用内存队列做排队,然后分发给底层不同的 worker 来处理

9. 如何保证 RabbitMQ 高可用的

RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式

9.1. 单机模式

Demo 级别的,一般就是你本地启动了玩玩儿的?,没人生产用单机模式。

9.2. 普通集群模式

意思就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。

你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个 queue 的读写操作

9.3. 镜像集群模式

这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思

这样的好处在于,你任何一个机器宕机了,没事儿,其它机器(节点)还包含了这个 queue 的完整数据,别的 consumer 都可以到其它节点上去消费数据。坏处在于,第一,这个性能开销也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据

10. 如何解决消息队列的延时以及过期失效问题

RabbtiMQ 是可以设置过期时间的,也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。那这就是第二个坑了。这就不是说数据会大量积压在 mq 里,而是大量的数据会直接搞丢。我们可以采取一个方案,就是批量重导。你只能手动写程序把那 1000 个订单给查出来,手动发到 mq 里去再补一次。


本站总访问量