Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >遇到了消息堆积,但是问题不大

遇到了消息堆积,但是问题不大

作者头像
Vincent-yuan
发布于 2021-11-04 08:12:21
发布于 2021-11-04 08:12:21
4720
举报
文章被收录于专栏:Vincent-yuanVincent-yuan

这一篇我们要说的话题是消息的堆积处理,其实这个话题还是挺大的,因为消息堆积还是真的很令人头疼的,当堆积的量很大的时候,这真的是个很暴躁的问题,不过这时候真考验大家冷静的处理问题的能力了

我们一起来分析分析有关问题吧

大量的消息堆积在MQ中几个小时还没解决怎么办呢

一般这种比较着急的问题,最好的办法就是临时扩容,用更快的速度来消费数据

1、临时建立一个新的Topic,然后调整queue的数量为原来的10倍或者20倍,根据堆积情况来决定

2、然后写一个临时分发消息的consumer程序,这个程序部署上去消费积压的消息,消费的就是刚刚新建的Topic,消费之后不做耗时的处理,只需要直接均匀的轮询将这些消息轮询的写入到临时创建的queue里面即可

3、然后增加相应倍数的机器来部署真正的consumer消费,注意这里的Topic,然后让这些consumer去真正的消费这些临时的queue里面的消息

不知道大家明白没有,很简单的道理,我给大家举个形象的例子

一个topic堵住了,新建一个topic去进行分流,临时将queue资源和consumer资源扩大10倍,将消息平均分配到这些新增的queue资源和consumer资源上,以正常10倍的速度来消费消息,等到这些堆积的消息消费完了,便可以恢复到原来的部署架构

这种只是用于临时解决一些异常情况导致的消息堆积的处理,如果消息经常出现堵塞的情况,那该考虑一下彻底增强系统的部署架构了

消息设置了过期时间,过期就丢了怎么办呢

在rabbitmq中,可以设置过期时间TTL,和Redis的过期时间一样,如果消息在queue中积压超过一定时间就会被rabbitmq清理掉,这个数据就没了

这样可能会造成大量的数据丢失

这种情况下上面的解决方案就不太合适了,可以采取批量重导的方案来解决,在系统流量比较低的时候,用程序去查询丢失的这部分数据,然后将消息重新发送到MQ中,把丢失的数据重新补回来

这也算是一种补偿任务吧,补偿任务一般是用于对定时跑批的一种补偿

分析下RocketMQ中的消息堆积原因

消息的堆积归根到底就是生产者生产消息的速度和消费者消费的速度不匹配导致的,输入的和消费的速度不统一

或许是突然搞了一波促销,系统业务量暴增,导致生产者发消息暴增,消费速度跟不上

也有可能是消费方出现失败的情况,疯狂重试,也或者就是消费方的消费能力太低了

RocketMQ是按照队列进行消息负载的,如果consumer中的一台机器由于硬件各方面原因导致该机器上的消息队列不能及时处理,就会造成整个消息队列的堆积

RocketMQ分为发布方和订阅方,双方都有负载均衡策略,默认都是采用平均分配,producer消息以轮询方式发送到消息队列queue中,broker将这些的queue再平均分配到属于同一个group id的订阅方集群

  • .如果消费者consumer机器数量和消息队列相等,则消息队列平均分配到每一个consumer上
  • 如果consumer数量大于消息队列数量,则超出消息队列数量的机器没有可以处理的消息队列
  • 若消息队列数量不是consumer的整数倍,则部分consumer会承担跟多的消息队列的消费任务

如果其中一台机器处理变慢,可能是机器硬件、系统、远程 RPC 调用或 Java GC 等原因导致分配至此机器上的 Queue 的消息不能及时处理 消息队列 RocketMQ 版的消息负载是按 Queue 为粒度维护,所以,整个 Queue 上的消息都会堆积

那说一下解决思路吧

我们知道了最根本原因是生产和消费速度不匹配导致的,这种问题要是经常出现,就是系统架构导致,这种需要考虑增加消费方的数量了 如果是搞促销的这种临时情况导致的,这种情况下系统应该会比较快的消化掉,堆积时间不会很快,如果搞促销时间很长,持续高流量时间很长,那没得办法,还是得加机器 经常出现这种消息堆积问题,需要先定位一下消费满的原因,也也可能是代码bug,导致多次重试,如果是bug则处理bug,优化下消费的逻辑 再者就要考虑水平扩容,增加Topic的queue数量和消费者的数量,这两者增加的时候需要考虑两边的平衡,队列数量一定要增加,不然新增加的消费数量者会导致无消息消费的尴尬场面,一个topic中的一个队列只会分配给一个消费者 消费者数量超过队列数量的时候,超出的部分消费者就无消息可以消费了

RocketMQ中消费完的消息去了哪里呢

消息的存储是一直存在于CommitLog文件中的,大家都知道CommitLog是以文件为单位存在的,而且RocketMQ的设计是只允许顺序写,也就意味着所有消息都是顺序的写入到这个文件中的 而每个消息的大小又不是定长的,所以这就决定了消息几乎不可能按照消息为单位进行删除,逻辑极其复杂 消息一旦被消费了之后是不会被立即清除的,还是会存在于CommitLog文件中的,那问题来了,消息未删除,RocketMQ是如何知道哪些消息已经被消费过,哪些还未消费呢 答案就是客户端会维护一个消息的offset,客户端拉取完消息之后,broker会随着响应体返回一个下一次拉取的位置,消费者会更新自己的下一次的pull的位置

CommitLog文件什么时候进行清除

消息存储到该文件之后,也是会被清理的,但是这个清理只会在下面这些条件中,任一条件成立的时候才会批量的删除CommitLog消息文件

  • 消息文件过期(默认72小时),且到达清理时点(默认是凌晨4点),删除过期文件。
  • 消息文件过期(默认72小时),且磁盘空间达到了水位线(默认75%),删除过期文件。
  • 磁盘已经达到必须释放的上限(85%水位线)的时候,则开始批量清理文件(无论是否过期),直到空间充足。

注:若磁盘空间达到危险水位线(默认90%),出于保护自身的目的,broker会拒绝写入服务。

为什么这么设计呢

CommitLog文件默认大小是1GB,在清理的时候属于大文件操作了,IO压力也是有的,这样设计该文件的优点我大概说几个,当然肯定还有些别的

只需要保存一份消息文件:一个消息如果需要被多个消费者组消费,消息只需要保存一份即可,消费进度单独保存,这样比较容易支撑强大的消息存储能力 支持回溯:把消息的消费位置的决定权放在客户端,只要消息还在,就可以消费,所以也就有了RocketMQ支持的回溯消费 像看视频一样,可以把镜头调到前面去,重新看一遍刚刚的视频 支持消息索引服务:RocketMQ中有一个索引文件,消息只要还存在于CommitLog中,就可以被搜索出来,方便排查问题

参考:https://mp.weixin.qq.com/s/darDDxORk7261vJAqg3Tmg

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
精选RocketMQ面试题[33题]
queue 就是来源于数据结构的 FIFO 队列。而 Topic 是个抽象的概念,每个 Topic 底层对应N个 queue,而数据也真实存在 queue 上的。
一行Java
2022/04/07
4.6K0
面试必备(背)--RocketMQ八股文系列
担任路由消息的提供者。生产者或消费者能够通过NameServer查找各Topic相应的Broker IP列表分别进行发送消息和消费消息。nameServer由多个无状态的节点构成,节点之间无任何信息同步。 broker会定期向NameServer以发送心跳包的方式,轮询向所有NameServer注册以下元数据信息:
微客鸟窝
2022/11/07
1K0
面试必备(背)--RocketMQ八股文系列
万字聊一聊RocketMQ一条消息短暂而又精彩的一生
我们都知道,消息是由业务系统在运行过程产生的,当我们的业务系统产生了消息,我们就可以调用RocketMQ提供的API向RocketMQ发送消息,就像下面这样
三友的java日记
2024/06/07
1640
万字聊一聊RocketMQ一条消息短暂而又精彩的一生
17 个方面,综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四个分布式消息队列
本文将从,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。
芋道源码
2019/05/15
1.6K0
分布式消息队列差异化总结,太全了!
本文将对Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ从17 个方面综合对比作为消息队列使用时的差异。
lyb-geek
2019/07/22
1.6K0
RocketMQ 设计原理与最佳实践
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
Java识堂
2021/06/01
1.2K0
RocketMQ 设计原理与最佳实践
面渣逆袭:RocketMQ二十三问
选择中间件的可以从这些维度来考虑:可靠性,性能,功能,可运维行,可拓展性,社区活跃度。目前常用的几个中间件,ActiveMQ作为“老古董”,市面上用的已经不多,其它几种:
三分恶
2022/05/11
1.3K0
面渣逆袭:RocketMQ二十三问
10分钟搞懂!消息队列选型全方位对比
导语 | 消息队列是分布式系统中重要的中间件,在高性能、高可用、低耦合等系统架构中扮演着重要作用。本文对Kafka、Pulsar、RocketMQ、RabbitMQ、NSQ这几个消息队列组件进行了一些调研,并整理了相关资料,为业务对MQ中间件选型提供参考。 一、概述 消息队列是分布式系统中重要的中间件,在高性能、高可用、低耦合等系统架构中扮演着重要作用。分布式系统可以借助消息队列的能力,轻松实现以下功能: 解耦,将一个流程的上游和下游拆开,上游专注生产消息,下游专注处理消息。 广播,一个上游生产的消息轻松被
腾讯云开发者
2022/02/17
14.3K0
RocketMQ详细介绍
RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、延时消息、消息回溯等(业务性比较关注)
默 语
2024/11/22
5420
RocketMQ详细介绍
RocketMq 基本扫盲
本篇是RocketMq扫盲,并不会讲到各个组件实现的细节内容,这里从整体全局的角度看关于RocketMq的整体设计。
阿东
2022/09/11
8520
RocketMq 基本扫盲
【MQ我可以讲一个小时】
应用场景,消息可靠投递,消息丢失,消息重复消费,消息的幂等性,消息的顺序性,消息队列积压,延迟队列,消息过期失效,消息队列的高可用
Java廖志伟
2022/09/29
3730
【MQ我可以讲一个小时】
聊聊 RocketMQ 4.X 消费逻辑
RocketMQ 是笔者非常喜欢的消息队列,4.9.X 版本是目前使用最广泛的版本,但它的消费逻辑相对较重,很多同学学习起来没有头绪。
勇哥java实战
2023/06/05
1.1K0
一篇文章把RabbitMQ、RocketMQ、Kafka三元归一
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/07/12
7700
一篇文章把RabbitMQ、RocketMQ、Kafka三元归一
消息队列经典十连问
大家好呀,我是捡田螺的小男孩。金三银四即将来临,整理了十道十分经典的消息队列面试题,看完肯定对面试有帮助的,大家一起加油哈~
捡田螺的小男孩
2022/04/06
8170
消息队列经典十连问
云原生中间件RocketMQ(一)基本概念&功能特性&架构设计&环境搭建
消息队列(Message Queue,简称 MQ)是构建分布式互联网应用的基础设施,通过 MQ 实现的松耦合架构设计可以提高系统可用性以及可扩展性,是适用于现代应用的最佳设计方案。
共饮一杯无
2022/11/28
1K0
云原生中间件RocketMQ(一)基本概念&功能特性&架构设计&环境搭建
RocketMQ
每个broker与nameserver集群的所有节点建立长连接,定时注册topic信息到所有nameserver。
用户5097014
2022/05/20
1.3K0
快速学习-RocketMQ设计理念
消息存储是RocketMQ中最为复杂和最为重要的一部分,本节将分别从RocketMQ的消息存储整体架构、PageCache与Mmap内存映射以及RocketMQ中两种不同的刷盘方式三方面来分别展开叙述。
cwl_java
2020/09/18
7320
RocketMQ学习总结
服务器上部署的RocketMq进程一般称之为Broker,Broker会接收Producer的消息,持久化到本地,然后push给Consumer,通常使用集群部署。主从之间会有数据同步
周同学
2020/06/30
1.4K0
RocketMQ学习总结
RocketMQ学习2-设计
消息存储是RocketMQ中最为复杂和最为重要的一部分,本节将分别从下面三方面来分别展开叙述。
Vincent-yuan
2021/11/08
9030
RocketMQ学习2-设计
2021-Java后端工程师面试指南-(消息队列)
面试指南系列,很多情况下不会去深挖细节,是小六六以被面试者的角色去回顾知识的一种方式,所以我默认大部分的东西,作为面试官的你,肯定是懂的。
用户9927510
2022/07/29
3690
2021-Java后端工程师面试指南-(消息队列)
相关推荐
精选RocketMQ面试题[33题]
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档