🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 1. 使用镜像的原因 如果 RabbitMQ 集群中只有一个 Broker 节点,那么该节点的失效将导致整体服务的临时性不可用,并且也可能会导致消息的丢失。可以将所有消息都设置为持久化,并且对应队列的durable属性也设置为true,但是这样仍然无法避免由于缓存导致的问题:因为消息在发送之后和被写入磁盘井执行刷盘动作之间存在一个短暂却会产生问题的时间窗。通过 publisherconfirm 机制能够确保客户端知道哪些消息己经存入磁盘,尽管如此,一般不希望遇到因单点故障导致的服务不可用。 <br/> 引入镜像队列(Mirror Queue)的机制,可以将队列镜像到集群中的其他 Broker 节点之上,**如果集群中的一个节点失效了,队列能自动地切换到镜像中的另一个节点上以保证服务的可用性**。 <br/> # 2. 搭建步骤 **1. 启动三台集群节点** **2. 随便找一个节点添加 policy** ![](https://img.kancloud.cn/df/ca/dfca892e7e6e6903157fcb05ffe21601_1896x961.jpg) ![](https://img.kancloud.cn/55/11/55116d2fc7cdd1b227c6d012b9e21523_1485x256.jpg) **3. 生成者,方便测试** ```java import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class Producer { private static final String QUEUE_NAME = "mirrior.my.queue"; public static void main(String[] args) throws Exception { // 1. 创建一个连接工厂 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.0.109"); factory.setUsername("admin"); factory.setPassword("admin"); // 2. channel 实现了自动 close 接口 自动关闭 不需要显示关闭 try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) { // 生成一个队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); String message = "hello world"; // 发送一个消息 channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println("消息发送完毕"); } } } ``` **4. 测试** (1)启动生产者,得到队列信息如下,node3为备份。 ![](https://img.kancloud.cn/e5/e9/e5e9d4d62648adae1d8cdb33cee21705_1540x416.jpg) (2)将node1停掉,node2变成了备份。 ```shell [root@node1 ~]# rabbitmqctl stop_app ``` ![](https://img.kancloud.cn/89/a8/89a8d5e91adba57b70a8ce0b28a711b7_1461x405.jpg) **5. 结论** 就算整个集群只剩下一台机器了 依然能消费队列里面的消息,说明队列里面的消息被镜像队列传递到相应机器里面了。