热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

消息队列把消息弄丢了怎么办?

消息队列会丢失消息吗?答案是肯定的,所以对于业务严谨的数据,我们要确保其在消息队列中的安全,不能丢。要想解决不丢的问题,首先要弄清楚消息是怎么丢的呢?丢消息的关键点有3个:Prod

消息队列会丢失消息吗?

答案是肯定的,所以对于业务严谨的数据,我们要确保其在消息队列中的安全,不能丢。

要想解决不丢的问题,首先要弄清楚 消息是怎么丢的呢?

丢消息的关键点有3个:



  • Producer 发送消息的过程

  • 消息队列的消息存储

  • Consumer 消费消息的过程

下面挨个看看都是怎么丢的,以及解决方案。

会以 RabbitMQ 和 Kafka 这两个常用的消息系统来说明。


1. Producer 弄丢消息

Producer 向 MQ 发消息,很简单,发过去就完事儿了。

但是,在发送图中是存在危险的,例如网络问题等等,导致 MQ 没有正常收到。

怎么解决呢? 思路很简单,让 MQ 发一个 接受确认声明(ack) 就行了,就像快递需要签收一样。

例如 RabbitMQ,有两种方式可以确保发送消息的安全。

1)事务消息

Producer 发送消息之前,先开启事务,然后再发送。

如果 RabbitMQ 没有正常收到消息,Producer 会收到异常信息,回滚事务。

如果正常接收了,Producer 就提交事务。

很可靠,但效率低,因为这个事务模式是同步的,会产生阻塞。

2)confirm 确认模式

Producer 开启 confirm 模式,发送消息的时候,RabbitMQ 会给这个消息分配一个唯一的 ID。

成功写入队列之后,RabbitMQ 会向 Producer 发送一个 ack 消息,说明此 ID 的消息已经成功发送。

confirm 模式还有一个回调机制,Producer 可以准备一个失败的接口,供 RabbitMQ 在接收失败时调用。

Producer 收到失败通知,或者超时了,可以执行相应的处理逻辑,例如重发。

confirm 模式是异步的,比事务消息更高效,使用更为广泛。

Kafka 也是使用的 ack 方式,使用方式很简单,只要配置:

ack=all

确保 Kafka 在完全接收成功后才发送确认通知,这样就一定不会发丢了。


2. MQ 在存储期间弄丢消息

MQ 成功接收消息之后,需要保存起来,等着 Consumer 消费。

在这个保存期间,也可以能丢失消息。

这通常是由 MQ 故障引起的。

RabbitMQ 想要保障消息不丢,需要开启持久化,消息就会写入磁盘。

即使 RabbitMQ 宕机了,只要磁盘没事儿,重启之后还可以重新把消息加载进来。

如果想进一步的保障消息安全,就需要配置 RabbitMQ 的镜像集群了,来确保高可用。

Kafka 是天然的分布式系统,Topic 分为多个 Partition,每个 Partition 又有多个副本。

Partition 的多个副本,分为 Leader 和 Follower。

Leader 负责处理消息的读写,Follower 负责备份。

前面说的 Kafka 配置 ack=all,就是告诉Kafka,Leader 和所有 Follower 全都接收到了,才算发送 ack 确认,只有 Leader 自己接收成功是不算的。

否则的话,如果 Leader 接收完成就告诉 Producer OK 了,在 Leader 同步给 Follower 之前,Leader 宕机了,Kafka 会从 Follower 中选举出新的 Leader。那么,老 Leader 在临终前没有同步的消息就丢失了。

为了保障消息的安全,这 4 个参数要设置好:

replication.factor

用于指定 Partition 副本的数量,必须大于 1,就是至少要有 2 个副本,一个 Leader 一个 Follower。

min.insync.replicas

用于指定几个副本成功写入才提交消息,只有提交之后的消息才能被 Consumer 消费。

此值至少大于 1,这样就保障 Leader 之外至少有一个副本同步到了这条消息,不怕 Leader 宕掉了。

acks=all

用于指定几个副本接收到消息之后向 Producer 发送 ack。例如值为 1,表示 Leader 收到就可以了,“all” 表示 “所有副本”,也可以写 “-1”,等同于 “all”。

retries=999

用于指定 Producer 发送失败后的重试次数,可以设为一个很大的数,表示失败了就重试,提升发送成功几率。


3. Consumer 弄丢消息

例如 Consumer 成功接收到了消息 “123”,MQ 就会移除这条消息。

但在 Consumer 处理完这条消息之前,宕机了。

Consumer 重启之后继续从 MQ 拿消息,这次拿到的就是下一条消息 “124”,那么 “123” 就丢了。

所以,Consumer 只是接收到消息是不够的,成功处理完成才行。

这就和 MQ 的消费确认机制有关了。

RabbitMQ 默认是 Consumer 成功接收消息之后就发送 ack 确认,RabbitMQ 就认为消费成功了。

关闭自动的 Consumer ack 就行,改为手动发送确认通知。

Kafka 的 Consumer 发送的不是 ack 确认,而是 offset,告诉 Kafka 已经消费到哪个位置了。

默认是 Consumer 接收后自动提交 offset,所以也需要关闭,改为手动提交。

小结一下,要想消息不丢,需要发消息的时候确认发送成功了,MQ 存储的时候要是高可靠的,Consumer 消费的时候,不能接收之后就确认,真正处理完成才行。

推荐阅读

OAuth2 图解

轻松理解 Kubernetes 的核心概念

开发者必须要了解的架构技术趋势:Service Mesh



推荐阅读
  • 本文将介绍一种扩展的ASP.NET MVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • OpenCV 2.4.9 源码解析:级联分类器的错误率与尺寸分析 ... [详细]
  • 本文详细介绍了使用响应文件在静默模式下安装和配置Oracle 11g的方法。硬件要求包括:内存至少1GB,具体可通过命令`grep -i memtotal /proc/meminfo`进行检查。此外,还提供了详细的步骤和注意事项,确保安装过程顺利进行。 ... [详细]
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • openGauss行存储核心架构及其页面组织详解
    行存储的核心架构和页面组织是实现DML操作、可见性判断及多种管理功能的基础。作为基于磁盘的存储引擎,行存储在设计上采用了段页式结构,以优化数据的存储和访问效率。这种设计不仅确保了数据的高效存储,还为行存储的各种高级功能提供了坚实的技术支持。 ... [详细]
  • 在Hive中合理配置Map和Reduce任务的数量对于优化不同场景下的性能至关重要。本文探讨了如何控制Hive任务中的Map数量,分析了当输入数据超过128MB时是否会自动拆分,以及Map数量是否越多越好的问题。通过实际案例和实验数据,本文提供了具体的配置建议,帮助用户在不同场景下实现最佳性能。 ... [详细]
  • 深入解析Java虚拟机内存模型(JMM)及其核心机制
    为了深入理解Java内存模型(JMM),首先需要对计算机硬件体系有全面的认识,尤其是CPU与主存之间的多级缓存架构。这些硬件特性直接影响了JMM的设计和实现,确保在多线程环境下数据的一致性和可见性。 ... [详细]
  • 优化Android BroadcastReceiver时需关注的关键事项与最佳实践
    在优化Android中的BroadcastReceiver时,开发者应关注若干关键事项并遵循最佳实践。本文探讨了在BroadcastReceiver中编码时可能遇到的意外异常及其解决方法,同时提供了提高性能和稳定性的建议。通过合理配置和使用BroadcastReceiver,可以有效避免常见的问题,如内存泄漏、响应延迟等,确保应用的高效运行。 ... [详细]
  • 深入理解Spark框架:RDD核心概念与操作详解
    RDD是Spark框架的核心计算模型,全称为弹性分布式数据集(Resilient Distributed Dataset)。本文详细解析了RDD的基本概念、特性及其在Spark中的关键操作,包括创建、转换和行动操作等,帮助读者深入理解Spark的工作原理和优化策略。通过具体示例和代码片段,进一步阐述了如何高效利用RDD进行大数据处理。 ... [详细]
  • 本文深入剖析了ScheduledThreadPoolExecutor的并发执行机制及其源代码,详细解读了该线程池如何在指定延时或定期执行任务,探讨了其内部的工作原理和优化策略,为开发者提供了宝贵的参考和实践指导。 ... [详细]
  • NoSQL数据库,即非关系型数据库,有时也被称作Not Only SQL,是一种区别于传统关系型数据库的管理系统。这类数据库设计用于处理大规模、高并发的数据存储与查询需求,特别适用于需要快速读写大量非结构化或半结构化数据的应用场景。NoSQL数据库通过牺牲部分一致性来换取更高的可扩展性和性能,支持分布式部署,能够有效应对互联网时代的海量数据挑战。 ... [详细]
  • 工程项目管理系统源码简洁+好用+全面工程项目管理系统
    ​​工程项目管理系统是指从事工程项目管理的企业(以下简称工程项目管理企业)受业主委托,按照合同约定,代表业主对工程项目的组织 ... [详细]
  • 分布式一致性算法:Paxos 的企业级实战
    一、简介首先我们这个平台是ES专题技术的分享平台,众所周知,ES是一个典型的分布式系统。在工作和学习中,我们可能都已经接触和学习过多种不同的分布式系统了,各 ... [详细]
  • Spring cloud微服务架构前后端分离博客系统,Vue+boot源码分享 ... [详细]
author-avatar
faerbersitko
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有