一文带你搞懂RabbitMQ 如何保证消息不丢失

RabbitMQ使用场景

  • 异步发送(验证码、短信、邮件)
  • MySQL和Redis,ES之间的数据同步
  • 分布式事务
  • 削峰填谷

什么情况下消息容易丢失

  •  消息未到达交换机
  • 消息未到达队列
  • 队列中消息丢失
  • 消费者未接收到消息

解决消息丢失的方法:

1、生产者确认机制

RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。

消息失败之后如何处理呢?

  • 回调方法即时重发
  • 记录日志
  • 保存到数据库然后定时重发,成功发送后即刻删除表中的数据

2、消息持久化

MQ默认是内存存储消息,开启持久化功能可以确保缓存在MQ中的消息不丢失。

1. 交换机持久化:

@Bean
public DirectExchange simpleExchange(){
    //三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除
    return new DirectExchange("simple.direct",true,false);
}

2. 队列持久化:

@Bean
public Queue simpleQueue(){
    //使用QueueBuilder构建队列,durable就是持久化的
    return QueueBuilder.durable("simple.queue").build();
}

3. 消息持久化,SpringAMQP中的消息默认是持久的,可以通过MessageProperties中的DeliveryMode来指定

Message msg = MessageBuilder
        .withBody(message.getBytes(StandardCharsets.UTF_8))  //消息体
        .setDeliveryMode(MessageDeliveryMode.PERSISTENT)  //持久化
        .build();

3、消费者确认

RabbitMQ支持消费者确认机制,即:消费者处理消息后可以向MQ发送ack回执,MQ收到ack回执后才会删除该消息。而SpringAMQP则允许配置三种确认模式:

  •  manual:手动ack,需要在业务代码结束后,调用api发送ack。
  • auto:自动ack,由Spring检测listener代码是否出现异常,没有异常则返回ack;抛出异常则返回nack。
  • none:关闭ack,MQ假定消费者获取消息后会成功处理,因此消息投递后立即被删除。

我们可以利用Spring的retry(重试)机制,再消费者出现异常时利用本地重试,设置重试次数,当次数达到了以后,如果消息依然失败,将消息投递到异常交换机,交由人工处理。

 面试题:RabbitMQ如何保证消息不丢失

候选人:我们当时MySQL和Redis的数据双写一致性就是采用RabbitMQ实现同步的,这里面就要求了消息的高可用性,我们要保证消息不丢失。主要从三个层面考虑:

第一个是开启生产者确认机制,确保生产者的消息能到达队列,如果报错可以先记录到日志中,再去修复数据。

第二个是开启持久化功能,确保消息未消费前在队列中不会丢失,其中的交换机、队列和消息都要做持久化。

第三个是开启消费者确认机制为auto,由Spring确认消息处理成功后完成ack,当然也需要设置一定的重试次数,我们当时设置了3次,如果重试3次还没有收到消息,就将失败后的消息投递到异常交换机中,交由人工处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/902201.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python查询并安装项目所依赖的所有包

引言 如果需要进行代码的移植,肯定少不了在另一台pc或者服务器上进行环境的搭建,那么首先是要知道在已有的工程的代码中用到了哪些包,此时,如果是用人工去一个一个的代码文件中去查看调用了哪些包,这个工作甚是繁琐。…

js面试问题笔记(一)

一.热门js面试 1.简述同步和异步的区别? 同步: 浏览器访问服务器请求,用户看到页面刷新 ,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作 异步: 浏览器访问服务器请求,用户正常操作,浏览器后端进行请求,等请求完,页面不刷新,新内容也会出现,用户看到…

【HarmonyOS Next】原生沉浸式界面

背景 在实际项目中,为了软件使用整体色调看起来统一,一般顶部和底部的颜色需要铺满整个手机屏幕。因此,这篇帖子是介绍设置的方法,也是应用沉浸式效果。如下图:底部的绿色延伸到上面的状态栏和下面的导航栏 UI 在鸿蒙…

Grid View 网格视图

GoTo DevExpress Data Grid 数据网格 Grid View 网格视图 GridView 是默认的数据网格视图,它以传统的表格格式显示数据。View 将数据源记录呈现为行,将数据源字段呈现为列。数据值显示在各个单元格中。 以下文档包含有关此表格布局的主要元素的深入信…

多线程——线程安全的集合类

目录 前言 一、多线程环境使用 ArrayList 1.进行加锁 2.使用 SynchronizedList 类 3.使用 CopyOnWriteArrayList 类 二、多线程环境使用队列 1.进行加锁 2.使用阻塞队列 三、多线程环境使用哈希表 1.Hashtable 2.ConcurrentHashMap (1)缩小锁…

vue文件转AST,并恢复成vue文件(适用于antdv版本升级)

vue文件转AST,并恢复成vue文件---antdvV3升级V4 vue文件转AST,重新转回原文件过程如何获取项目路径读取项目文件,判断文件类型分别获取vue文件 template js(vue2和vue3)处理vue 文件template部分处理vue script部分uti…

【线下+线上会议|国内外双会场】2024年第四届数字化社会与智能系统国际学术会议(DSInS 2024)-悉尼/郑州双会场

2024年第四届数字化社会与智能系统国际学术会议(DSInS 2024)-悉尼/郑州双会场 2024 4th International Conference on Digital Society and Intelligent Systems 会议官网:www.dsins.org 2024 4th International Conference on Digital Soc…

龙迅#LT89101 适用于 MIPI DSI/CSI摄像头和 LVDS 中继信号延长功能,分辨率可支持 1080P@60HZ!

1. 描述 Lontium LT89101 是一款高性能 MIPI DSI/CSI-2 和 LVDS 中继器,用于汽车系统应用的移动显示或摄像头信号整形。 LT89101采用先进的 CMOS 工艺制造,并采用小外形 7.5mm x 7.5mm QFN64 封装。该封装符合 RoHS 标准,额定工作温度范围为 …

MySQL8.0.40编译安装

近期MySQL发布了8.0.40版本,与之前的版本相比,部分依赖包发生了变化,因此重新编译一版,也便于大家参考。 1. 下载源码 选择对应的版本、选择源码、操作系统 如果没有登录或者没有MySQL官网账号,可以选择只下载 2. 进…

element 按钮变形 el-button样式异常

什么都没动,element UI的按钮变形了,莫名其妙,连官网的也变形了,换了其它浏览器又正常, 难道这是element UI的问题?NO,是浏览器的插件影响到了!去扩展插件里面一个个关闭扩展&#x…

MySql中的锁的分类

锁的分类 MySQL锁可以按模式分类为:乐观锁与悲观锁。按粒度分可以分为全局锁、表级锁、页级锁、行级锁。按属性可以分为:共享锁、排它锁。按状态分为:意向共享锁、意向排它锁。按算法分为:间隙锁、临键锁、记录锁。 二、全局锁、表…

ClickHouse与各种组件的关系

ClickHouse和其他组件关系如下: Flink支持ClickHouse Sink支持Hive/SparkSQL数据批量导入ClickHouseHetuEngine支持ClickHouse数据源常用第三方工具如DBeaver支持ClickHouse对接ClickHouse依赖ZooKeeper实现了分布式DDL执行以及ReplicatedMergeTree表主备节点之间的…

多线程—— JUC 的常见类

目录 前言 一、Callable 接口 1.Callable 介绍 2.代码示例 3.创建线程的方式 二、ReentrantLock 类 1.ReentrantLock 介绍 2.代码示例 3.与 synchronized 的区别 三、信号量 Semaphore 类 1.Semaphore 介绍 2.代码示例 3.保证线程安全的方式 四、CountDownLatch …

二、Spring的执行流程

文章目录 1. spring的初始化过程1.1 ClassPathXmlApplicationContext的构造方法1.2 refresh方法(核心流程)1.2.1 prepareRefresh() 方法1.2.2 obtainFreshBeanFactory() 方法1.2.3 prepareBeanFactory() 方法1.2.4 invokeBeanFactoryPostProcessors() 方…

(linux驱动学习 - 12). IIC 驱动实验

目录 一.IIC 总线驱动相关结构体与函数 1.i2c_adapter 结构体 2.i2c_algorithm 结构体 3.向系统注册设置好的 i2c_adapter 结构体 - i2c_add_adapter 4.向系统注册设置好的 i2c_adapter 结构体 - i2c_add_numbered_adapter 5.删除 I2C 适配器 - i2c_del_adapter 二.IIC 设…

【C++算法】11.滑动窗口_最大连续1的个数lll

文章目录 题目链接:题目描述:解法C 算法代码:图解 题目链接: 1004. 最大连续 1 的个数 III 题目描述: 解法 解法一:暴力枚举zero计数器 转化找出最长的子数组,0的个数不超过k个。 例如&#xf…

计算机网络——有连接传输层协议TCP

序号 序号一般不从0开始,这个在双方建立连接后约定一个数 这样做可以避免网络中滞留的TCP段对新的连接的干扰

Flutter状态管理

StatefulWidget按状态划分StatelessWidgetStatefulWidget 按照作用域划分组件内私有状态实现跨组件状态管理全局状态 状态组件的组成 DataTableInheritedWidget生命周期无状态组件有状态组件initState()didChangeDependencies()build()setState()didUpdateWidget()deactivate()…

Redis 集群 总结

前言 相关系列 《Redis & 目录》(持续更新)《Redis & 集群 & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Redis & 集群 & 总结》(学习总结/最新最准/持续更新)《Redis & 集群…

二十二、Python基础语法(模块)

模块(module):在python中,每个代码文件就是一个模块,在模块中定义的变量、函数、类别人都可以直接使用,如果想要使用别人写好的模块,就必须先导入别人的模块,模块名须满足标识符规则(由字母、数…