消息积压了如何处理?

欢迎大家到我的博客阅读这篇文章。消息积压了如何处理? - 胤凯 (oyto.github.io)

在系统中使用消息队列的时候,消息积压这个问题也经常遇到,并且这个问题还不太好解决。

消息积压的直接原因通常是,系统中的某个部分出现了性能问题,来不及处理上游发送的消息,才会导致消息积压。

下面我们来分析下,在使用消息队列的时候,如何优化代码的性能,避免出现消息积压,以及遇到了消息积压问题,该如何进行处理,最大程度地避免消息积压对业务的影响。

优化性能来避免消息积压

对于绝大多数使用消息队列的业务来说,消息队列本身的处理能力要远大于业务能力的处理能力。主流的一些消息队列的单个节点,消息收发的能力可以达到每秒钟处理几万至几十万条消息的水平,还可以通过水平扩展 Broker 的实例数成倍地提升处理能力。

而一般的业务系统需要处理的业务逻辑远比消息队列复杂,单个节点每秒钟可以处理几百到几千次请求,已经可以算是性能非常好的了。所以,对于消息队列的性能优化,我们更应该关注,在消息的收发两端,我们的业务代码怎么和消息队列配合,达到一个最佳的性能。

发送端性能优化

发送端业务代码的处理性能,实际上和消息队列的关系并不打,因为发送端都是先执行自己的业务逻辑,再发送消息。如果系统发送消息的性能上不去,可以优先检查一下是不是发送消息之前的业务逻辑耗时太多导致的。

对于发送消息的业务逻辑,只要注意设置好合适的并发和批量大小,就可以达到很好的发送性能。

我们之前的文章中讲过 Producer 发送消息的过程,Producer 发消息给 Broker,Broker 收到消息后返回确认响应,这是一次完整的交互。假设这一次交互的平均时延是 1 ms,我们把这 1ms 的时间分解开,它包括了下面这些步骤的耗时:

  • 发送端准备数据、序列号消息、构造请求等逻辑的时间,即发送端在发送网络请求之前的耗时

  • 发送消息和返回响应在网络传输中的耗时

  • Broker 处理消息的时延

如果是单线程发送,每次只发送 1 条消息,那么每秒只能发送 1000ms / 1ms * 1 条 /ms = 1000 条 消息,这种情况下并不能发挥出消息队列的全部实力。

这个时候,我们可以选择增加每次发送消息的批量大小或增加并发,都能成倍地增加性能,具体的选择,还是需要根据业务需求来进行选择。

比如说,你的消息发送端是一个微服务,主要接受 RPC 请求处理在线业务。很自然的,微服务在处理每次请求的时候,就在当前线程直接发送消息就可以了,因为所有 RPC 框架都是多线程支持多并发的,自然也就实现了并行发送消息。并且在线业务比较在意的是请求响应时延,选择批量发送必然会影响 RPC 服务的时延。这种情况,比较明智的方式就是通过并发来提升发送性能。

如果你的系统是一个离线分析系统,离线系统在性能上的需求是什么呢?它不关心时延,更注重整个系统的吞吐量。发送端的数据都是来自于数据库,这种情况就更适合批量发送,你可以批量从数据库读取数据,然后批量来发送消息,同样用少量的并发就可以获得非常高的吞吐量。

消费端性能优化

在使用消息队列的时候,大部分性能问题都出现在消费端,如果消费的速度跟不上发送端生产消息的速度,就会造成消息积压。如果这种性能倒挂的问题是暂时的,那问题不大,等消费端的性能恢复之后,超过发送端的性能,那积压的消息是可以被消费完的。

要是消费端的性能一直低于生产端,时间长了整个系统就会出现问题:要么消息队列的存储被填满无法继续提供服务,要么消息丢失,对于整个系统来说都是严重故障。

所以,这种设计系统的时候,一定要保证消费端的消费性能要高于生产端的发送性能,这样才能保证健康的继续运行。

消费端的性能优化还可以通过水平扩展来处理,即增加消费的并发数来提升总体的消费性能。特别需要注意的一点是,在扩容 Consumer 的实例数量的同时,必须同步扩容主题中的分区(也叫队列)数量,确保 Consumer 的实例数和分区数量是相等的。如果 Consumer 的实例数量超过分区数量,这样的扩容实际上是没有效果的。原因我们之前讲过,因为对于消费者来说,在每个分区上实际上只能支持单线程消费。

有很多消费程序,是这样解决消费慢的问题的:

业务处理逻辑比较慢,很难优化,为了避免消息积压,在收到消息的 OnMessage 方法中,不处理任务业务逻辑,而是把这个消息放到内存队列里就返回了。然后启动多个业务线程,这些线程里是真正处理消息的业务逻辑,这些线程从内存队列里取消息处理,这样它就解决了单个 Consumer 不能并行消费的问题。

这个方法看似很完美,但是如果收消息的节点宕机,在内存队列中还没有来得及处理这些消息就会丢失。关于 ”消息丢失“ 问题,可以查看 《如何确保消息不会丢失》这篇文章。

消息积压了该如何处理?

上述两种情况都是在系统设计上的情况,还有一种情况是在系统正常运转时,没有积压或者少量积压后很快就消费掉了,但是某一个时刻,突然开始消息积压并持续上涨。这种情况需要在短时间内找到消息积压的原因,并迅速解决问题,才不至于影响业务。

能导致消息突然积压,最粗粒度的原因只有两种:要么是发送变快了,要么是消费变慢了。

大部分消息队列都内置了监控功能,只要通过监控数据,很容易确定是哪种原因。如果是单位时间发送的消息增加,比如赶上大促销或者抢购,短时间内不太可能优化消费端的代码来提升消费性能,唯一的办法就是通过扩容消费端的实例数来提升总体的消费能力。

如果短时间内没有足够的服务器资源进行扩容,没办法的办法是,将系统降级,通过关闭一些不重要的业务,减少发送方发送的数据量,最低限度让系统还能正常运转,服务一些重要业务。

还有一种不太常见的情况,你通过监控发现,无论是发送消息的速度还是消费消息的速度和原来都没什么变化,这时候你需要检查一下你的消费端,是不是消费失败导致的一条消息反复消费这种情况比较多,这种情况也会拖慢整个系统的消费速度。

如果监控到消费变慢了,你需要检查你的消费实例,分析一下是什么原因导致消费变慢。优先检查一下日志是否有大量的消费错误,如果没有错误的话,可以通过打印堆栈信息,看一下你的消费线程是不是卡在什么地方不动了,比如触发了死锁或者卡在等待某些资源上了。

小结

这篇文章,我们主要讨论了两个问题,一个是如何在设计系统时从消息队列的收发两端优化系统性能,提前预防消息堆积;另一个问题是,当系统发生消息积压后,该如何处理。

优化收发消息性能,预防积压的方法有两种:增加批量或者增加并发,在发送端两种方法都可以使用,在消费端需要注意的是,增加并发需要同步扩容分区数量,否则是不起作用的。

而对于系统发生消息积压的情况,需要先解决积压再分析原因,快速解决积压的方法就是通过水平扩容增加 Consumer 的实例数量,退一步的办法就是将系统降级,关闭一些不重要的业务,保证重要业务的正常运行。

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

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

相关文章

经典ctf ping题目详解 青少年CTF-WEB-PingMe02

题目环境: 根据题目名称可知 这是一道CTF-WEB方向常考的知识点:ping地址 随便ping一个地址查看接受的数据包?ip0.0.0.0 有回显数据,尝试列出目录文件 堆叠命令使用’;作为命令之间的连接符,当上一个命令完成后,继续执…

Flink1.17 DataStream API

目录 一.执行环境(Execution Environment) 1.1 创建执行环境 1.2 执行模式 1.3 触发程序执行 二.源算子(Source) 2.1 从集合中读取数据 2.2 从文件读取数据 2.3 从 RabbitMQ 中读取数据 2.4 从数据生成器读取数据 2.5 …

【产品应用】一体化伺服电机在系留无人机中的应用

一体化伺服电机是一种将电机、驱动器、编码器结合在一起的伺服系统,具有高精度控制、快速响应和高效运行等优点。系留无人机则是一种通过绳索或链条与地面设施连接的无人机,能够实现长时间的稳定悬停和空中作业。 01.设备简介 电源线牵引装置&#xff1…

MATLAB Simulink和S7-1200PLC MOBUSTCP通信

MATLAB Simulink和SMART PLC OPC通信详细配置请查看下面文章链接: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读749次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的…

人工智能-循环神经网络通过时间反向传播

到目前为止,我们已经反复提到像梯度爆炸或梯度消失, 以及需要对循环神经网络分离梯度。 例如,我们在序列上调用了detach函数。 为了能够快速构建模型并了解其工作原理, 上面所说的这些概念都没有得到充分的解释。 本节将更深入地探…

YOLO目标检测——烟雾检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用:烟雾检测数据集可用于监控烟雾情况,实现火灾的早期预警。数据集说明:烟雾检测数据集,真实场景的高质量图片数据,数据场景丰富,含烟雾1个类别标签说明:使用lableimg标注软件标注&am…

Ant Design for Figma设计系统组件库 支持变量 非社区版

Ant Design for Figma 是基于 Ant Design 设计系统的 Figma 组件库,提供丰富的 UI 组件和交互功能,帮助设计师快速构建高质量的 Figma 设计稿。 Ant Design for Figma 继承了 Ant Design 的设计理念和风格,提供丰富的 UI 组件和交互功能&…

如何在el-tree懒加载并且包含下级的情况下进行数据回显-01

在项目中做需求,遇到一个比较棘手的问题,el-tree懒加载在包含下级的时候,需要做回显,将选中的数据再次勾选上,在处理这个需求的时候有两点是比较困难的: el-tree是懒加载的,包含下级需要一层一…

【10套模拟】【6】

关键字: 有向图入度、无向图度、一次深度优先、快速排序平均性能、折半查找、判断是否是二叉排序树、链式直接入插入排序

腾讯云服务器怎么买便宜?腾讯云服务器新人专享限时特惠购买链接

腾讯云作为国内领先的云计算服务提供商之一,为个人用户和企业用户提供了多种优惠活动。这些活动不仅能帮助用户节省成本,还能提升企业的效益。本文将介绍腾讯云的多重优惠活动,让用户能够以更优惠的价格购买和续费云服务器。 腾讯云双十一领…

HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理

1、 新建应用时选择与自己真机匹配的sdk版本 查看自己设备sdk版本 创建时先择匹配版本: 2、 根据报错提示连接打开处理方案 3、查询真机版本对应的compileSdkVersion 和 compatibleSdkVersion 提示3.1版本之后和3.1版本之前的不同命令(此处为3.0版…

数学建模 | 灰色预测原理及python实现

目录 一、灰色预测的原理 二、灰色预测的应用及python实现 一、灰色预测的原理 灰色预测是以灰色模型为基础,灰色模型GM(n,h)是微分方程模型,可用于描述对象做长期、连续、动态的反应。其中,n代表微分方程式的阶数,h代表微分方…

课程设计(毕业设计)—基于机器学习(CNN+opencv+python)的车牌识别—(可远程调试)计算机专业课程设计(毕业设计)

基于机器学习(CNNopencvpython)的车牌识别 下载本文机器学习(CNNopencvpython)的车牌识别系统完整的代码和参考报告链接(或者可以联系博主koukou(壹壹23七2五六98),获取源码和报告)https://download.csdn.net/download/shooter7/88548767此处…

使用Pandas进行时间重采样,充分挖掘数据价值

大家好,时间序列数据蕴含着很大价值,通过重采样技术可以提升原始数据的表现形式。本文将介绍数据重采样方法和工具,提升数据可视化技巧。 在进行时间数据可视化时,数据重采样是至关重要且非常有用的,它支持控制数据的…

合伙人如何承担合伙公司债务

合伙企业有不同的组织方式,包括普通合伙企业、特殊的普通合伙企业、有限合伙企业这三种,合伙人对于合伙企业的债务承担方式有以下几种情形: 1.普通合伙人合伙企业债务的承担 普通合伙企业由普通合伙人组成,合伙人对合伙企业债务承…

【开源】基于Vue和SpringBoot的数据可视化的智慧河南大屏

项目编号: S 059 ,文末获取源码。 \color{red}{项目编号:S059,文末获取源码。} 项目编号:S059,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 数据模块 …

Swagger示例

对于项目完成后不用写文档,好处还是蛮大的 不需要关注项目其他 只关注接口与实体类即可 SpringBoot项目 依赖 <!--Swagger依赖--> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version…

Buildroot 添加 Qt 支持

Buildroot 添加 Qt 支持 lqonlylove 于 2022-12-03 13:37:34 发布 阅读量2.8k 收藏 12 点赞数3 分类专栏: 根文件系统制作 文章标签: qt buildroot 版权 ​编辑根文件系统制作专栏收录该内容 2 篇文章0 订阅 订阅专栏 一、制作根文件系统 Buildroot 制作根文件系统_l…

python基础练习题库实验1

题目1 使用以下变量 product_code“377B” product_name“牛肉汤” product_size“250mL” product_price2.15 使用字符串加法编写一个print语句&#xff0c;以便生成以下精确输出&#xff1a; 377B&#xff1a;牛肉汤&#xff0c;250mL 代码 product_code "377B"…

springcloudalibaba-3

一、Nacos Config入门 1. 搭建nacos环境【使用现有的nacos环境即可】 使用之前的即可 2. 在微服务中引入nacos的依赖 <!-- nacos配置依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-…