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

①生产阶段,生产者创建消息,经过网络发送到rabbit服务器

②消息存储阶段,首先被发送到交换器然后经过路由算法,到达队列,等待被拉取消费

③消费阶段,消费者经过网络从rabbit服务器拉取消息进行消费

这三个阶段都有可能消息丢失,下面一一分析。

消息存储阶段

正常情况下,我们使用BasicPublish方法发送消息到交换器上然后路由到队列上面,消费者还没进行消费,此时服务器重启了(队列、交换器使用默认的创建方式),会发生什么?答案是:消息丢失。原因很简单:消息在内存中,没有刷盘,并且,他们默认是非持久化的,服务重启之后,它们需要重新创建,消息自然就丢失!

还好,Rabbit提供持久化的机制,队列、交换器创建的时候,durable属性设置为true,同时消息投递模式(delivery mode)设置为2,则消息标记成持久化。这样可以避免服务器重启消息丢失的情况。

发送阶段

由于发布操作不返回任何信息给生产者,那你怎么知道服务器是否已经持久化了持久消息到硬盘呢?服务器可能在把消息写入磁盘前就宕机了,消息因此而丢失!

有。)

Rabbit提供两中解决方案,事务,但是性能会大打折扣,而且会使生产者应用程序产生同步。生产环境一般不会采用;另外一种方案是确认模式。也很简单,消息路由给所有匹配的订阅队列中,之后会异步的告之生产者。使用channel.ConfirmSelect()方法,使信道开启确认模式。然后注入两个回调函数,ack和nack事件。

channel.BasicAcks += (sender, ev) =>
{
Console.WriteLine("消息已经确认收到" + ev.DeliveryTag); }; channel.BasicNacks += (sender, ev) =>
{
Console.WriteLine("消息未确认" + ev.DeliveryTag);
};

消费阶段

你可能会问,消费端消息怎么会丢失呢?Rabbitmq提供自动和手动确认消息,然后消息从队列中移除。如果autoAck为true,自动确认模式,服务器就会在消息发给消费端后自动将其出队。如果因为某些原因连接中断了,或者你的消费端应用发生了故障,那么消息就会丢失!

通过把AutoAck设置为false,手工确认,告知服务器,消息已经处理了,可以进行消息出队删除。

 channel.BasicConsume(queue: queueName,
autoAck: false,
consumer: consumer);
consumer.Received += (model, ea) =>
{
//dosometing
channel.BasicAck(ea.DeliveryTag, false);//确认
};

小结:如果做了以上的处理,那么消息就不会跟你躲猫猫了。这里有性能的问题,消息持久化,是要刷到磁盘上的会影响投递速度,并且消息确认也会影响到消息投递速度。不基本上能够满足需求了。如果不能满足性能需求,可以使用其他方法,比如 在每次发送消息的时候,都包含应答队列的名称,这样消费者就可以回发应答以确认接受到了。如果消息应答未在合理时间范围内到达,生产者就重新发送消息。

RabbitMq如何确保消息不丢失的更多相关文章

  1. 如何保证RabbitMQ的消息不丢失及其背后的原理

    一.消息为什么丢失 RabbitMQ默认情况下的交换机和队列以及消息是非持久化的,也就是说在服务器重启或者宕机恢复后,之前创建的交换机和队列都将不复存在,之前未消费的消息也就消失不见了.原因在于每个队 ...

  2. RabbitMQ 保证消息不丢失

    参考:https://www.imooc.com/article/49814 发送消息的时候,加上messageId字段,数据库记录消息日志表 ,插入的时候为发送中 当收到消息的时候,更改为已发送 , ...

  3. rabbitmq保证数据不丢失方案

    rabbitmq如何保证消息的可靠性 1.保证消息不丢失 1.1.开启事务(不推荐) 1.2.开启confirm(推荐) 1.3.开启RabbitMQ的持久化(交换机.队列.消息) 1.4.关闭Rab ...

  4. rabbitmq之确保消息不丢失

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

  5. RabbitMQ防止消息丢失

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

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

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

  7. 基于springboot工程浅谈整合rabbitmq怎么样防止消息发送mq不丢失和消费mq的消息防止丢失

    本文只针对springboot整合rabbitmq的消息防丢失,话不多说,上干货.... 设置发送mq消息不丢失实现思路 执行的方案: 第一步,要对队列,消息以及交换机进行持久化操作(保存到物理磁盘中 ...

  8. RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得

    前言 首先说一点,企业中最常用的实际上既不是RocketMQ,也不是Kafka,而是RabbitMQ. RocketMQ很强大,但主要是阿里推广自己的云产品而开源出来的一款消息队列,其实中小企业用Ro ...

  9. RabbitMQ入门-消息派发那些事儿

    在上篇<RabbitMQ-高效的Work模式>中,我们了解了Work模型,该模型包括一个生产者,一个消息队列和多个消费者. 我们已经通过实例看出消息队列中的消息是如何被一个或者多个消费者消 ...

随机推荐

  1. 修改Markdown神器[Typora]的主题样式

    修改Markdown神器[Typora]的主题样式 Typora是一款专注写作的工具,基于markdown标记语言来完成写作.出于以下原因决定替换主题样式: 1.自带的样式比较low,想替换一款高大上 ...

  2. oracle impdp 数据迁移 至RDS 亚马逊云

    背景: 公司年底打算将aws rds11.2.0.4 oracle 数据库升级到19c,所以需要进行升级测试,所以需要我把线上的库数据迁移到一台测试的rds oracle 亚马逊云的数据库中,然后升级 ...

  3. Rider 2018 激活码

    http://jetbrains.license.laucyun.com (Lower of 2017.3) http://13.112.247.119:8000 (All version, espe ...

  4. 在一台电脑上,添加多个Git的ssh key

    Git的第一套公秘钥默认名为 id_rsa ,如果你想要生成另外一个公钥,比如 aysee ,你也可以使用任何你喜欢的名字. 步骤如下:(总共四大操作) 一.生成ssh key 1.生成一个新的自定义 ...

  5. VMware安装Centos7 -九五小庞

    VMware安装Centos7超详细过程(图文) https://blog.csdn.net/babyxue/article/details/80970526 安装centos7的时候 启动会提示Pl ...

  6. 2申请高德地图key 初始化地图

    https://console.amap.com/dev/key/app vue-amap-基于-vue-2x-与高德的地图组件 https://elemefe.github.io/vue-amap/ ...

  7. 0vscode基本插件

    Bracket Pair Colorizer auto-close-tag Auto Rename Tag Bracket Pair Colorizer Dracula ESLint  Code Sp ...

  8. 跟着兄弟连系统学习Linux-【day05】

    day05-20200602 p19.其他文件搜索命令 (百度搜索everything,安装,可以实现Windows秒级搜索文件)Linux中同样可以实现此功能. [locate 文件名]locate ...

  9. 跟着兄弟连系统学习Linux-【day04】

    day04-20200601 p15.链接文件 [ln -s 原文件   连接文件]软连接,所有人都可以操作软连接文件(实际上是取决于原文件的权限),类似于Windows的快捷方式,方便进行管理.软连 ...

  10. C++STL中vector的初始化

    vector的初始化有很多方式,在N维初始化时还会一些容易出现错误的地方.下面进行总结 以下的总结均以int作为模板参数 一维vector的初始化 vector的构造函数通常来说有五种,如下: vec ...