[TOC]
# 1. 使用鏡像的原因
如果 RabbitMQ 集群中只有一個 Broker 節點,那么該節點的失效將導致整體服務的臨時性不可用,并且也可能會導致消息的丟失。可以將所有消息都設置為持久化,并且對應隊列的durable屬性也設置為true,但是這樣仍然無法避免由于緩存導致的問題:因為消息在發送之后和被寫入磁盤井執行刷盤動作之間存在一個短暫卻會產生問題的時間窗。通過 publisherconfirm 機制能夠確保客戶端知道哪些消息己經存入磁盤,盡管如此,一般不希望遇到因單點故障導致的服務不可用。
<br/>
引入鏡像隊列(Mirror Queue)的機制,可以將隊列鏡像到集群中的其他 Broker 節點之上,**如果集群中的一個節點失效了,隊列能自動地切換到鏡像中的另一個節點上以保證服務的可用性**。
<br/>
# 2. 搭建步驟
**1. 啟動三臺集群節點**
**2. 隨便找一個節點添加 policy**


**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為備份。

(2)將node1停掉,node2變成了備份。
```shell
[root@node1 ~]# rabbitmqctl stop_app
```

**5. 結論**
就算整個集群只剩下一臺機器了 依然能消費隊列里面的消息,說明隊列里面的消息被鏡像隊列傳遞到相應機器里面了。
- 消息隊列
- 什么是MQ
- MQ的作用
- MQ的分類
- MQ的選擇
- RabbitMQ
- RabbitMQ是什么
- 四大核心概念
- 工作原理
- 環境搭建
- windows系統下的搭建
- centos7系統下的搭建
- 常用命令
- 服務相關命令
- 管理用戶命令
- 管理隊列命令
- 第一個RabbitMQ程序
- 工作隊列
- 輪詢分發消息
- 消息應答
- 持久化
- 發布確認
- 發布確認原理
- 發布確認策略
- 交換機概念
- 交換機類型
- 無名交換機
- Fanout交換機
- Direct交換機
- Topic交換機
- 死信隊列
- 死信概念
- 死信來源
- 死信實戰
- 延遲隊列
- 什么是延遲隊列
- TTL設置方式
- 隊列TTL延遲隊列
- 消息TTL延遲隊列
- 插件打造延遲隊列
- 延遲隊列總結
- 發布確認高級
- 代碼實現
- 回退消息
- 備份交換機
- 冪等性
- 冪等性概念
- 消息重復消費
- 消費端冪等性保障
- 優先級隊列
- 使用場景
- 設置優先級
- 惰性隊列
- 什么是惰性隊列
- 隊列的兩種模式
- 聲明惰性隊列
- RabbitMQ集群
- 為什么要搭建集群
- 集群搭建步驟
- 集群工作方式
- 脫離集群
- 鏡像隊列
- 高可用負載均衡