一、消息为什么丢失

RabbitMQ默认情况下的交换机和队列以及消息是非持久化的,也就是说在服务器重启或者宕机恢复后,之前创建的交换机和队列都将不复存在,之前未消费的消息也就消失不见了。原因在于每个队列和交换机的durable属性。该属性默认情况是false,它决定了RabbitMQ是否需要在崩溃或者重启之后重新创建队列(或者交换机)。

二、持久化交换机和队列

将交换机和队列的durable属性设置为true,这样你就不需要在服务器断电后重新创建队列和交换机了。你也许会认为把队列和交换机的durable属性设置为true就足够可以让消息幸免于重启后丢失了,真的是这样吗?队列和交换机当然必须被设置为true,但光这样做还不够。
能从AMQP服务器崩溃中恢复的消息,我们称之为持久化消息。在消息发布前,通过把它的“投递默认”( delivery
mode)选项设置为2(AMQP客户端可能会使用人性化的常量来代替数值)来把消息标记成持久化。到目前为止,消息还只是被表示为持久化的,但是它还必须被发布到持久化的交换机中,并到达持久化的队列中才行。如果不是这样的话,则包含持久化消息的队列(或者交换机)会在Rabbit崩溃重启后不复存在,从而导致消息丢失。

三、持久化消息

因此,如果消息想要从Rabbit崩溃中恢复,那么消息必须满足以下条件:
1. 把它的投递默认选项设置为持久化
2. 发送到持久化的交换机
3. 到达持久化的队列

做到以上三点,你就不需要担心发送到Rabbit服务器的消息因服务器崩溃等其它原因而丢失了。

四、如何做到消息持久化的

RabbitMQ确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件。当发布一个持久性消息到持久交换机上时,Rabbit会在消息提交到日志文件后才发送响应。记住,之后这条消息如果路由到了非持久队列的话,它会自动从持久性日志中移除,并且无法从服务器重启中恢复。如果你使用持久性消息的话,则确保之前提到的持久性消息的那三点都必须做到位。一旦你从持久性队列中消费了一个持久性消息的话(并且确认了它),RabbitMQ会在持久化日志中把这条消息标记为等待垃圾收集。在你消费持久性消息前,如果RabbitMQ重启的话,服务器会自动重建交换机和队列(以及绑定),重播持久性日志文件的消息到合适的队列或者交换机上(取决于Rabbit服务器宕机的时候,消息处在路由过程的哪个环节)。

虽然持久化消息可以做到消息的不丢失,但持久化的消息在进入队列前会被写到磁盘,这个过程比写到内存慢得多,所以会严重的影响性能,可能导致消息的吞吐量降低10倍不止。所以,在做消息持久化前,一定要认真考虑性能和需求之间的平衡关系。

如何保证RabbitMQ的消息不丢失及其背后的原理的更多相关文章

  1. RabbitMq如何确保消息不丢失

    上篇写了掌握Rabbitmq几个重要概念,从一条消息说起,这篇来总结关于消息丢失让人头痛的事情.网络故障.服务器重启.硬盘损坏等都会导致消息的丢失.消息从生产到消费主要结果以下几个阶段如下图. ①生产 ...

  2. Kafka如何保证消息不丢失不重复

    首先需要思考下边几个问题: 消息丢失是什么造成的,从生产端和消费端两个角度来考虑 消息重复是什么造成的,从生产端和消费端两个角度来考虑 如何保证消息有序 如果保证消息不重不漏,损失的是什么 大概总结下 ...

  3. RabbitMQ 如何保证消息不丢失?

    RabbitMQ一般情况很少丢失,但是不能排除意外,为了保证我们自己系统高可用,我们必须作出更好完善措施,保证系统的稳定性. 下面来介绍下,如何保证消息的绝对不丢失的问题,下面分享的绝对干货,都是在知 ...

  4. rabbitmq之确保消息不丢失

    1.背景引入 在使用消息中间件(rabbitmq)时,令开发者最头痛的就是防止消息丢失问题,而消息丢失可能发生的位置主要为三种,分别为(1)消息发送到MQ中消费者消费未成功时突然宕机:(2)消息发送到 ...

  5. Storm入门(五)Twitter Storm如何保证消息不丢失

    转自:http://xumingming.sinaapp.com/127/twitter-storm如何保证消息不丢失/ storm保证从spout发出的每个tuple都会被完全处理.这篇文章介绍st ...

  6. RabbitMQ防止消息丢失

    转载请注明出处 0.目录 RabbitMQ-从基础到实战(1)— Hello RabbitMQ RabbitMQ-从基础到实战(3)— 消息的交换 1.简介 RabbitMQ中,消息丢失可以简单的分为 ...

  7. 【转】Twitter Storm如何保证消息不丢失

    Twitter Storm如何保证消息不丢失 发表于 2011 年 09 月 30 日 由 xumingming 作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者 ...

  8. RabbitMQ如何保证发送端消息的可靠投递

    消息发布者向RabbitMQ进行消息投递时默认情况下是不返回发布者该条消息在broker中的状态的,也就是说发布者不知道这条消息是否真的抵达RabbitMQ的broker之上,也因此会发生消息丢失的情 ...

  9. 关于MQ的几件小事(四)如何保证消息不丢失

    1.mq原则 数据不能多,也不能少,不能多是说消息不能重复消费,这个我们上一节已解决:不能少,就是说不能丢失数据.如果mq传递的是非常核心的消息,支撑核心的业务,那么这种场景是一定不能丢失数据的. 2 ...

随机推荐

  1. JProfiler_SN_8_x key

    按默认选择“Single or evaluation license”Name 和 Company 随意-----------------------忧郁的分割线------------------- ...

  2. Linux不用使用软件把纯文本文档转换成PDF文件的方法

    当你有一大堆文本文件要维护的时候,把它们转换成PDF文档会好一些.比如,PDF更适合打印,因为PDF文档有预定义布局.除此之外,还可以减少文档被意外修改的风险. 要将文本文件转换成PDF格式,你要按照 ...

  3. Python之filter筛选数据工具

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python之filter筛选数据工具 #http://python.jobbole.com/82597/ ...

  4. 【laravel5.4】自定义404、503等页面

    1.处理自定义错误或不存在页面:生产环境一定要关闭debug模式. public function render($request, Exception $exception) { if ($exce ...

  5. HDUOJ----4502吉哥系列故事——临时工计划

    吉哥系列故事——临时工计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  6. HDUOJ-----Brave Game

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. 移动对meta的定义(转)

    以下是meta每个属性详解 尤其要注意的是content里多个属性的设置一定要用分号+空格来隔开,如果不规范将不会起作用. 一.<meta http-equiv="Content-Ty ...

  8. SQL SERVER SELECT语句中加锁选项的详细说明 [转]

    SQL Server提供了强大而完备的锁机制来帮助实现数据库系统的并发性和高性能.用户既能使用SQL Server的缺省设置也可以在select 语句中使用“加锁选项”来实现预期的效果. 本文介绍了S ...

  9. python练习笔记——模拟双色球随机输出情况

    编写Python函数:完成一个双色球彩票的模拟生成过程, 其中前六个为蓝色球,数字范围1-33,不可重复.最后一个为红色球 1-16. 使用random完成,最后将7个数进行排列放到列表中 # 引入r ...

  10. Python学习笔记011——内置函数eval()

    1 描述 eval()  函数用来执行一个字符串表达式,并返回表达式的值 2 语法 原文 eval(expression[, globals=None[, locals=None]]) express ...