赞
踩
参考文章:
RabbitMQ——入门介绍
《RabbitMQ 实战指南》朱忠华著
(1)MQ 指的是 Message Queue(消息队列),其本质上是个队列(FIFO 先进先出),它是一种在分布式系统中用于异步通信的技术。消息队列可以让不同的组件(例如应用程序、进程、服务等)通过发送和接收消息来进行通信,这些消息被保存在队列中,直到被接收方处理。
(2)MQ 的作用如下:
(1)消费者生产者模型 (Producer-Consumer Model) 是一种并发编程模型,通常用于解决生产者和消费者之间的数据共享和同步问题。在该模型中,生产者负责生成数据并将其添加到共享数据结构中,而消费者则负责从共享数据结构中获取数据并进行处理。
(2)具体来说,生产者将数据放入共享缓冲区中,消费者从共享缓冲区中取出数据进行处理。如果共享缓冲区已满,则生产者需要等待,直到有空间可用。同样,如果共享缓冲区为空,则消费者需要等待,直到有数据可用。这个模型通过同步机制来实现生产者和消费者之间的协作,以确保数据的正确性和一致性。
(3)生产者消费者模型常用于多线程编程、进程间通信、消息队列等场景中。例如,在消息队列中,生产者将消息发送到队列中,而消费者从队列中获取消息进行处理。这种模型能够有效地解耦生产者和消费者,提高系统的可扩展性和可靠性。
(1)RabbitMQ 是 AMQP 协议的 Erlang 的实现(RabbitMQ 也支持 STOMP2、 MQTT3 等协议)。AMQP 的模型架构和 RabbitMQ 的模型架构是一样的。RabbitMQ 中的交换器、交换器类型、队列、绑定、路由键等都是遵循的 AMQP 协议中相应的概念。
(2)AMQP 协议本身包括三层:
Queue.Declare
命令声明一个队列或者使用 Basic.Consume
订阅消费一个队列中的消息。(1)RabbitMQ 是一个开源的消息中间件,它实现了高度灵活的消息队列模式。它是使用 Erlang
语言开发的,基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议),并且提供了许多客户端库,包括Java、Python、Ruby等,使得开发者可以方便地与其进行交互。
(2)RabbitMQ 的具体特点可以概括为以下几点:
RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上, RabbitMQ 就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说,RabbitMQ 模型更像是一种交换机模型。RabbitMQ 的整体模型架构如下图所示:
(1)Producer:生产者,就是投递消息的一方。生产者创建消息,然后发布到 RabbitMQ 中。消息一般可以包含 2 个部分:消息体和标签。消息体也可以称之为 payload
,在实际应用中,消息体般是一个带有业务逻辑结构的数据,比如一个 JSON 字符串。当然可以进一步对这个消息体进行序列化操作。消息的标签用来表述这条消息,比如一个交换器的名称和一个路由键。生产者把消息交由 RabbitMQ,RabbitMQ 之后会根据标签把消息发送给感兴趣的消费者。
(2)Consumer:消费者,就是接收消息的一方。消费者连接到 RabbitMQ 服务器,并订阅到队列上,当消费者消费一条消息时,只是消费消息的消息体 (payload) 在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只有消息体,消费者也只会消费到消息体,也就不知道消息的生产者是谁,当然消费者也不需要知道。
(3)Broker:消息中间件的服务节点。对 RabbitMQ 来说, 一个 RabbitMQ Broker 简单地看作 RabbitMQ 服务节点或者 RabbitMQ 服务实例。大多数情况下也可以将一个 RabbitMQ Broker 看作一台 RabbitMQ 服务器。
Queue:队列,是 RabbitMQ 的内部对象,用于存储消息。RabbitMQ 的生产者生产消息井最终技递到队列中,消费者可以从队列中获取消息并消费。多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin ,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息井处理,如下图所示:
(1)Exchange:交换机,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道如何处理它接收到的消息,是将这些消息推送到特定队列还是推送到多个队列,亦或者是把消息丢弃,这个由交换机类型决定,如下图所示:
(2)RoutingKey:路由键。生产者将消息发给交换器的时候, 一般会指定一个 RoutingKey
,用来指定这个消息的路由规则,而这个 RoutingKey 需要与交换器类型和绑定键 (BindingKey
) 合使用才能最终生效。在交换器类型和绑定键 (BindingKey) 固定的情况下,生产者可以在发送消息给交换器时,通过指定 RoutingKey 来决定消息流向哪里。
(3)Binding:绑定。RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一 绑定键 BindingKey
,这样RabbitMQ 就知道如何正确地将消息路由到队列了,如下图所示:
生产者将消息发送给交换器时, 需要一个 RoutingKey
,当 BindingKey
和 RoutingKey
相匹时(后面将两者和合称为路由键), 消息会被路由到对应的队列中。在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的 BindingKey。BindingKey 并不是在所有的情况下都生效,它依赖于交换器类型。
通过下面的比喻来理解交换器、路由键、绑定这几个概念:交换器相当于投递包裹的邮箱,
RoutingKey
相当于填写在包裹上的地址,BindingKey
相当于包裹目的地,当填写在包裹上的地址和实际想要投递的地址相匹配时,那么这个包裹就会被正确投递到目的地,最后这个目的地的"主人"一一队列可以保留这个裹。如果填写目的地址出错,邮递员不能正确投递到目的地,包裹可能会回退给寄件人,也有可能被丢弃。
(1)交换机 (Exchange) 是一种用于将消息路由到一个或多个队列的组件。生产者发送消息到交换机,交换机根据特定的路由规则将消息路由到一个或多个队列,然后消费者从队列中获取消息进行处理。
(2)交换机必须确切知道如何处理收到的消息,是应该把这些消息放到特定队列,还是说把他们到许多队列中,还是说应该丢弃它们。这就的由交换机的类型来决定。RabbitMQ 支持以下四种类型的交换机:
Fanout Exchange
:把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。Direct Exchange
:把消息路由到那些 BindingKey
和 RoutingKey
完全匹配的队列中。Topic Exchange
:在匹配规则上进行了扩展,它与 direct 类型的交换器相似,也是将消息路由到 RoutingKey
和 BindingKey
相匹配的队列中,但这里的匹配规则有些不同,它约定:根据消息的 Routing Key 和通配符将消息路由到一个或多个队列。
RoutingKey
为一个点号 "."
分隔的字符串(被点号 "."
分隔开的每一段独立的字符串称为一个单词),例如 “com.rabbitmq.client”、“java.util.concurrent”、“com.hidden.client”;BindingKey
和 RoutingKey
一样也是点号 "."
分隔的字符串;BindingKey
中可以存在两种特殊字符串 “*” 和 “#”,用于做模糊匹配,其中 "*"
用于匹配一个单词,"#"
用于匹配多规格单词(可以是零个);Headers Exchange
:该类型的交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中 headers 属性
进行匹配。在绑定队列和交换器时制定一组键值对,当发送消息到交换器时,RabbitMQ 会获取到该消息的 headers(也是一个键值对的形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers 类型的交换器性能会很差,而且也不实用,基本上不会看到它的存在。(3)不同类型的交换机适用于不同的应用场景。例如:
Fanout Exchange
适用于将消息广播给所有绑定到该交换机上的队列;Direct Exchange
适用于将消息路由到特定的队列;Topic Exchange
适用于模糊匹配 Routing Key;Headers Exchange
适用于根据消息的 Headers 属性进行路由,但实际上很少使用;(1)我们将 RabbitMQ 的工作原理分为生成者发送消息和消费者接收消息这两部分:
RabbitMQ Broker
,建立一个连接 (Connection),开启一个信道 (Channel);RabbitMQ Broker
,其中包含路由键、交换器等信息。RabbitMQ Broker
,建立一个连接 (Connection) ,开启一个信道 (Channel);RabbitMQ Broker
请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作;RabbitMQ Broker
回应并投递相应队列中的消息, 消费者接收消息;(2)下面介绍两个新的概念:Connection
和 Channel
。我们知道无论是生者还是消费者,都需要和 RabbitMQ Broker
建立连接,这个连接就是一条 TCP 连接,也就是 Connection。一旦 TCP 连接建立起来,客户端紧接着可以创建一个 AMQP 信道 (Channel) ,每个信道都会被指派一个唯一的 ID。信道是建立在 Connection 之上的虚拟连接, RabbitMQ 处理的每条 AMQP 指令都是通过信道完成的。
(3)我们完全可以直接使用 Connection 就能完成信道的工作,为什么还要引入信道呢?试想这样一个场景,一个应用程序中有很多个线程需要从 RabbitMQ 中消费消息,或者生产消息,那么必然需要建立很多个 Connection
,也就是许多个 TCP 连接。然而对于操作系统而言,建立和销毁 TCP 连接是非常昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现。 RabbitMQ 采用类似 NIO (Non-blocking I/O) 的做法,选择 TCP 连接复用,不仅可以减少性能开销,同时也便于管理。
为了避免 TCP 连接的开销和并发数受限的性能瓶颈,RabbitMQ 采用了信道 (Channel) 的方式来传输数据。信道是生产者、消费者与 RabbitMQ 通信的通道,它是建立在 TCP 连接上的虚拟连接,而且每个 TCP 连接可以拥有多个信道,没有数量限制。因此,RabbitMQ 可以在一条 TCP 连接上建立成百上千个信道,以实现多线程处理。这样,多个线程可以共享同一条 TCP 连接,而每个信道在 RabbitMQ 中都有唯一的 ID,从而确保信道的私有性。每个信道对应一个线程的使用,这种方式使得 RabbitMQ 能够高效地利用系统资源。
默认情况下发送消息的操作是不会返回任何信息给生产者的,也就是默认情况下生产者是不知道消息有没有正确地到达服务器。如果在消息到达服务器之前已经丢失,持久化操作也解决不了这个问题,因为消息根本没有到达 RabbitMQ 针对这个问题,提供了两种解决方式:
(1)RabbitMQ 支持事务机制,通过事务机制可以保证消息的原子性、一致性和持久性。在 RabbitMQ 中,事务机制通过 AMQP (Advanced Message Queuing Protocol) 事务模型来实现。RabbitMQ 客户端中与事务机制相关的方法有以下三个:
channel.txSelect
:用于将当前的信道设置成事务模式;channel.txCommit
:用于提交事务;channel.txRollback
:用于事务回滚。(2)在通过 channel.txSelect 方法开启事务之后,我们便可以发布消息给 RabbitMQ 了:
channel.txRollback
方法来实现事务回滚。(3)注意这里的 RabbitMQ 中的事务机制与大多数数据库中的事务概念并不相同,需要注意区分。关键示例代码如下所示:
channel.txSelect();
channel.basicPublish(EXCHANGE_NAME,ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN,
"transaction messages".getBytes());
channel.txCommit();
上面代码对应的 AMQP 协议流转过程如下图所示:
(1)事务确实能够解决消息发送方和 RabbitMQ 之间消息确认的问题,只有消息成功被 RabbitMQ 接收,事务才能提交成功,否则便可在捕获异常之后进行事务回滚,与此同时可以进行消息重发。
(2)但是使用事务机制会“吸干” RabbitMQ 的性能,因为事务机制在一条消息发送之后会使发送端阻塞,以等待 RabbitMQ 的回应,之后才能继续发送下一条消息。那么有没有更好的方法既能保证消息发送方确认消息已经正确送达,又能基本上不带来性能上的损失呢?从 AMQP 协议层面来看并没有更好的办法,但是 RabbitMQ 提供了一个改进方案,即发送方确认机制。
(1)在 RabbitMQ 中,发布确认 (Publish/Confirm) 指的是生产者发送消息到 RabbitMQ 服务器后,等待服务器确认已经接收到消息的过程。具体来说,当生产者通过 RabbitMQ 的 AMQP 协议发送消息到服务器时,可以指定一个回调函数,用于在服务器确认接收到消息时进行处理。如果服务器成功接收到消息,就会调用该回调函数进行通知。如果服务器无法接收到消息,则会触发异常处理。
(2)生产者将信道设置成 confirm(确认)模式,一旦信道进入 confirm 模式,所有在该信道上面发布的消息都会被指派一个唯一的 ID(从 1 开始),一旦消息被投递到所有匹配的队列之后,RabbitMQ 就会发送一个确认 (Basic.Ack) 给生产者(包含消息的唯一 ID),这就使得生产者知晓消息已经正确到达了目的地了。如果消息和队列是可持久化的,那么确认消息会在消息写入磁盘之后发出。RabbitMQ 回传给生产者的确认消息中的 deliveryTag
包含了确认消息的序号,此外 RabbitMQ 也可以设置 channel.basicAck
方法中的 multiple
参数,表示到这个序号之前的所有消息都已经得到了处理,可以参考下图。
如果 RabbitMQ 因为自身内部错误导致消息丢失,就会发送一条 nack (Basic.Nack)命令,生产者应用程序同样可以在回调方法中处理该 nack 命令。生产者通过调用 channel.confirmSelect
方法(即 Confirm.Select 命令)将信道设置为 confirm 模式,之后 RabbitMQ 会返回 Confirm.Select-Ok
命令表示同意生产者将当前信道设置为 confirm 模式。所有被发送的后续消息都被 ack 或者 nack 一次,不会出现一条消
息既被 ack 又被 nack 的情况,并且 RabbitMQ 也并没有对消息被 confirm 的快慢做任何保证。
(1)在 RabbitMQ 中,单独确认、批量确认和异步确认模式是发布确认机制的不同实现方式。
channel.confirmSelect()
方法启用确认模式。channel.waitForConfirms()
方法来等待确认。该方法会阻塞当前线程,直到收到对应消息的确认信息或超时。channel.waitForConfirms()
方法等待 RabbitMQ 服务器返回全部消息的确认信息。channel.addConfirmListener()
方法中可以添加 ConfirmListener
这个回调接口,这个 ConfirmListener 接口包含两个方法:handleAck
和 handleNack
,分别用来处理 RabbitMQ 回传的 Basic.Ack
和 Basic.Nack
。在这两个方法中都包含有一个参数deliveryTag
(在发布确认模式下用来标记消息的唯一有序序号)。我们需要为每一个信道维护一个 “unconfirm” 的消息序号集合,每发送一条消息,集合中的元素加 1。每当调用 ConfirmListener 中的 handleAck 方法时,“unconfirm”集合中删掉相应的一条(multiple 设置为 false)或者多条(multiple 设置为 true)记录。从程序运行效率上来看,这个 “unconfirm” 集合最好采用有序集合 SortedSet 的存储结构。(2)总结:
注意:事务机制和发布确认机制两者是互斥的,不能共存!
(1)当消息在一个队列中变成死信 (dead message) 之后,它能被重新被发送到另一个交换器中,这个交换器就是死信交换机 (Dead-Letter-Exchange, DLX)
,绑定 DLX 的队列就称之为死信队列 (Dead-Letter Queue, DLQ)
。死信队列是指用于处理无法被消费者正常处理的消息的特殊队列。消息变成死信一般是由于以下几种情况:
(2)DLX 是一个正常的交换器,和一般的交换器没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列中存在死信时,RabbitMQ 就会自动地将这个消息新发布到设置的 DLX ,进而被路由到另一个队列,即死信队列。通过在 channel.queueDeclare
方法中设置 x-dead-letter-exchange
参数来为这个队列添加 DLX。
(3)通过使用死信队列,可以使得无法被正常处理的消息得到有效的处理,避免了因为消息被“遗弃”而造成的资源浪费,具体应用场景如下:
(1)延迟队列指用来存放需要在指定时间被处理的消息的队列。在 AMQP 协议中,或者 RabbitMQ 本身没有直接支持延迟队列的功能,但是可以通过 DLX 和 TTL 模拟出延迟队列的功能。具体来说,当一个消息被发送到延迟队列时,可以设置消息的 TTL 参数,指定该消息需要被延迟的时间。RabbitMQ 会在消息的 TTL 时间到达后,将该消息发送到一个特定的交换机,然后根据指定的路由键将该消息路由到对应的队列中,从而实现消息的延迟投递。
(2)延迟队列在实际应用中有很多的应用场景,例如:
(1)在 RabbitMQ 中设置死信队列需要以下几个步骤:
queue.declare
和 exchange.declare
方法进行创建和声明。queue.declare
方法,并设置 x-dead-letter-exchange
和 x-dead-letter-routing-key
参数来指定死信队列的交换机和路由键。
x-dead-letter-exchange
:指定死信消息发送到的交换机。x-dead-letter-routing-key
:指定死信消息的路由键。(2)需要注意的是,在设置死信队列时还可以配置其他参数,如消息过期时间、最大重试次数等,以满足具体的业务需求。
(1)优先级队列是指一种可以根据消息的优先级进行排序和处理的队列,可以通过设置队列的 x-max-priority
参数来实现。具体来说,当一个消息被发送到优先级队列时,可以为该消息设置一个优先级参数。RabbitMQ 会根据消息的优先级对消息进行排序,并优先处理优先级高的消息。如果两个消息的优先级相同,则按照先进先出的原则进行处理。
(2)优先级队列在实际应用中有很多的应用场景,例如:
(3)总之,优先级队列是 RabbitMQ 中非常有用的一种特性,可以帮助我们优化消息的处理顺序,提高消息的实时性和重要性,适用于很多不同的业务场景。
(1)核心步骤如下:
x-max-priority
参数来指定队列的最大优先级。(2)示例代码如下:
Map<String, Object> params = new HashMap();
params.put("x-max-priority", 10);
channel.queueDeclare("hello", true, false, false, params);
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
注意:消费者需要等待消息已经发送到队列中才去消费(即不能消费地太快,否则优先级队列来不及对消息进行排序),这样才有机会对消息进行排序。
(1)在消息队列系统中,幂等性是指同一条消息被处理多次时,处理的结果保持一致。
举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等。
(2)在 RabbitMQ 中,消息的幂等性可以通过以下方式来保证:
(3)在 RabbitMQ 中保证消息的幂等性非常重要,因为在消息队列中,同一条消息可能会被多次消费。如果消息的处理结果不保持一致,可能会导致数据不一致或业务错误。因此,需要在实现消费者时考虑消息的幂等性,保证消息的处理结果是可预期的。
(1)在 RabbitMQ 中,消息持久化是指将消息存储到磁盘上,以确保即使在 RabbitMQ 服务器意外崩溃或重启时,也能保证消息的安全性和可靠性。与之相对的是非持久化的消息,这种消息只会被存储在内存中,如果 RabbitMQ 服务器意外崩溃或重启,这些消息将会丢失。
(2)要将消息持久化,需要同时对队列和消息进行持久化设置。在创建队列时,可以设置 durable 参数为 true,表示该队列是持久化的。例如,以下代码创建了一个名为 test_queue 的持久化队列:
channel.queueDeclare('test_queue', durable=True)
对于要发送的消息,也需要设置持久化属性。例如,以下代码创建了一个名为 message 的持久化消息:
channel.basicPublish("exchange", 'test_queue', "Hello World!", MessageProperties.PERSISTENT_TEXT_PLAIN)
需要注意的是,将消息设置为持久化会对性能产生一定的影响,因为需要将消息写入磁盘。在生产环境中,需要权衡可靠性和性能,选择合适的持久化策略。
要解决消息队列的延时和过期失效问题,可以采取以下方法:
(1)RabbitMQ 本身并不直接支持严格的消息顺序性,因为它是一个并发处理消息的分布式系统,多个消费者可以同时处理不同的消息。但是可以通过以下方法帮助实现近似的消息顺序性:
(2)为了保证 RabbitMQ 中消息的可靠性,可以采取以下措施:
persistent
,同时在队列声明时将 durable
参数设置为 true
。(1)RabbitMQ 支持多种工作模式,包括以下几种常用的模式:
(2)不同的工作模式适用于不同的业务场景和需求,可以根据实际情况选择合适的工作模式来实现消息的传输和处理。
(1)在 RabbitMQ 中,集群是指将多个 RabbitMQ 服务器连接在一起,共同处理消息队列。集群可以提高系统的可用性和可扩展性,避免单点故障和瓶颈问题,支持水平扩展。
(2)要搭建 RabbitMQ 集群,可以按照以下步骤:
rabbitmq-server -detached
rabbitmqctl stop_app
# rabbitmqctl stop 会将 Erlang 虚拟机关闭,rabbitmqctl stop_app 只关闭 RabbitMQ 服务
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@node1
# 只启动应用服务
rabbitmqctl start_app
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@node2
rabbitmqctl start_app
# 在任意一个节点上都可查看
rabbitmqctl cluster_status
# 创建账号
rabbitmqctl add_user admin 123
# 设置用户角色
rabbitmqctl set_user_tags admin administrator
# 设置用户权限
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
登录 Web 管理页面便可以查看该集群的相关信息
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
rabbitmqctl cluster_status
# node1 上执行
rabbitmqctl forget_cluster_node rabbit@node2
(1)要保证 RabbitMQ 的高可用性,可以采取以下措施:
(2)综合应用以上措施,能够提高 RabbitMQ 的高可用性,保证系统在节点故障或网络问题等情况下的稳定运行。需要根据实际情况和需求选择合适的策略和配置方式。
(1)RabbitMQ 中的惰性队列 (Lazy Queue) 是指一种可以延迟加载消息的队列。与普通的队列不同,惰性队列的消息在被消费之前不会被完全加载到内存中,而是在消费者开始消费时才会被加载。具体来说,当一个消息被发送到惰性队列时,该消息会被存储到磁盘中,而不是存储在内存中。当消费者开始消费该队列时,RabbitMQ 会逐个从磁盘中读取消息,并将消息加载到内存中进行处理。这种方式可以避免队列过大导致内存溢出的问题,同时也能够提高队列的性能和扩展性。
(2)队列具备两种模式:default
和 lazy
。默认的为 default
模式,在 3.6.0 之前的版本无须做任何变更。lazy
模式即为惰性队列的模式,可以通过调用 channel.queueDeclare
方法的时候在参数中设置,也可以通过 Policy
的方式设置,如果一个队列同时使用这两种方式设置,那么 Policy
的方式具备更高的优先级。如果要通过声明的方式改变已有队列的模式,那么只能先删除队列,然后再重新声明一个新的。在队列声明的时候可以通过 x-queue-mode
参数来设置队列的模式,取值为 default
和 lazy
。
(3)惰性队列在实际应用中有很多的应用场景,例如:
(1)RabbitMQ 中的镜像队列 (Mirrored Queue) 是一种特殊的队列配置,通过将队列在多个节点之间进行备份或复制,实现数据的冗余存储,提高消息的可靠性和容灾能力。在镜像队列中,主节点 (Master) 上的消息会被同步地复制到一个或多个备份节点 (Slave),从而保持备份队列与主队列的一致性。当主节点发生故障或不可用时,备份节点可以接管消息的处理,确保消息的持久化和可靠性。
(2)镜像队列可以用于以下应用场景:
需要注意的是,使用镜像队列会增加系统的资源消耗和网络传输开销。因此,在配置镜像队列时需要根据实际情况考虑节点数量、网络带宽和延迟,以及对数据一致性和可用性的要求,综合平衡资源和性能。此外,镜像队列需要使用 RabbitMQ 的集群功能进行配置和管理。
(3)需要注意的是,镜像队列会增加系统的负载,因为它会将消息复制到多个节点。因此,在配置镜像队列时需要考虑系统的性能和可扩展性。另外,镜像队列还需要在集群中进行配置,以确保消息在多个节点之间同步。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。