个人名片:
博主:酒徒ᝰ.
个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来。
本篇励志:三人行,必有我师焉。
本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》,SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 点击观看
二、消息可靠性
2. 消息持久化
生产者确认可以确保消息投递到RabbitMQ的队列中,但是消息发送到RabbitMQ以后,如果突然宕机,也可能导致消息丢失。
要想确保消息在RabbitMQ中安全保存,必须开启消息持久化机制。
- 交换机持久化 : 默认非持久化
- 队列持久化 : 默认非持久化
- 消息持久化 : 默认持久化
默认情况下,通过SpringAMQP使用mq的都是持久化的。
- 交换机持久化
RabbitMQ中交换机默认是非持久化的,mq重启后就丢失。
SpringAMQP中可以通过代码指定交换机持久化:
@Bean
public DirectExchange simpleExchange(){
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
return new DirectExchange("simple.direct", true, false);
}
可以在RabbitMQ控制台看到持久化的交换机都会带上
D
的标示:
- 队列持久化
RabbitMQ中队列默认是非持久化的,mq重启后就丢失。
SpringAMQP中可以通过代码指定交换机持久化:
@Bean
public Queue simpleQueue(){
// 使用QueueBuilder构建队列,durable就是持久化的
return QueueBuilder.durable("simple.queue").build();
}
可以在RabbitMQ控制台看到持久化的队列都会带上
D
的标示:
- 消息持久化
利用SpringAMQP发送消息时,可以设置消息的属性(MessageProperties),指定delivery-mode:
- 1:非持久化
- 2:持久化
非持久化的消息在mq重启后,消息就没了
持久化消息代码
/**
* 持久化消息测试
*/
@Test
public void testDurableMessage() {
//创建持久化消息
Message message = MessageBuilder
.withBody("hello, ttl queue".getBytes(StandardCharsets.UTF_8))
.setDeliveryMode(MessageDeliveryMode.PERSISTENT)
.build();
//消息id
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
//发送消息
rabbitTemplate.convertAndSend("simple.queue", message, correlationData);
//记录日志
log.debug("消息发送成功");
}
重启docker,消息依然存在。
注意:
- routingkey在队列没有绑定交换机的时候,可以使用队列名。
上面的代码示例,simple.queue是队列,但是没有绑定交换机。