前言
本章講解RabbitMQ的持久化機制
方法
1.概念
我們知道,存到隊列中的消息一旦丟失,那後果是不堪設想的。例如:消費者端因爲某種原因宕機了!
RabbitMQ 的消息默認存放在內存上面,如果不特別聲明設置,消息不會持久化保存到硬盤上面的,如果節點重啓或者意外crash掉,消息就會丟失。所以就要對消息進行持久化處理。
RabbitMQ的持久化機制是它的一大看點,它有辦法解決我們上面說的問題。
2.問題重現
我們複製一份前面章節的Direct交換器的示例Provider和Consumer工程代碼:
我們對provider的測試代碼稍微做一點修改:
package cn.edu.ccut;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class RabbitMQTest {
@Autowired
private Provider provider;
@Test
public void testSendMsg() throws Exception{
int num = 0;
while(true){
num++;
Thread.sleep(2000);
provider.sendMsg("hello rabbitmq ! "+num);
}
}
}
我們每兩秒發送一次消息,然後將消息進行編號!
接下來我們正常演示程序,觀察控制檯輸出:
接下來我們模仿消費者端突然掛掉!!!
本次掛掉的時候恰好接收到了第21條消息:
但是Provider還在源源不斷的發送消息!
接下來我們啓動消費者端,模擬修復了消費者,觀察控制檯輸出:
我們發現,它重新從第67條消息開始接收,顯然我們22-66的消息丟掉了!!!,這是會出大事情的!!
那麼問題出現在哪裏呢?注意看這個配置:
該配置表示隊列是一個臨時隊列,當消費者端關閉時,消息隊列將自動刪除!
3.問題修復
經過上面的分析,我們很容易發現了問題的原因!
接下來我們將這個autoDelete屬性設置爲false,再次正常運行程序:
我們依舊讓他在第21條消息接收完畢後掛掉!
我們稍後再次啓動我們的消費者端,觀察控制檯輸出:
我們發現,它繼續的從22條開始接收,完美的實現了消息的持久化!