前言
本章讲解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条开始接收,完美的实现了消息的持久化!