RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑:
(1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到服务器呢,如果中间发生网络异常等情况呢?消息必然会丢失!
(2)RabbitMQ如果没有设置队列持久化,RabbitMQ服务器重后队列的元数据会丢失,消息自然也会丢失!
(3)RabbitMQ如果消费者设置自动确认,即autoAck为true,那么不管消费者发生什么情况,该消息会自动从队列中移除,实际上消费者有可能挂掉,消息必然会丢失!
(4)RabbitMQ中的消息如果没有匹配到队列时,那么消息也会丢失!
本文其实也就是结合以上四个方面进行讲解的,主要参考《RabbitMQ实战指南》(有需要PDF电子书的可以评论或者私信我),本文截图也来自其中,另外可以对一些RabbitMQ的概念的认识可以参考我的上两篇博文认识RabbitMQ交换机模型、RabbitMQ是如何运转的?
一、设置mandotory参数、AE备份交换器
针对前言中的第(4)个问题,我们可以通过设置mandotory参数与AE备份交换器来解决
1、mandotory参数1)当为true时,交换器无法根据自身的类型和路由键找到一个符合条件的队列,此时RabbitMQ会调用Basic.Return命令将消息返回给生产者,消息将不会丢失
2)当为false时,消息将会被直接丢弃。
3)RabbitMQ通过addReturnListener添加ReturnLisener监听器监听获取没有被正确路由到合适队列的消息。
channel.basicPublish(EXCHANGE NAME, "", true,
MessageProperties.PERSISTENT_TEXT_PLAIN,
"mandatory test".getBytes());
channel.addReturnListener(new ReturnListener(){
public void handleReturn(int replyCode, String replyText,
String exchange, String routingKey,
AMQP.BasicProperties basicProperties,
byte[] body) throws IOException {
String message = new String(body);
System.out.println("Basic.Return 返回的结果是: " + message);
}
});
.