爱陪小樱桃

导航

 

问题:当消费速度跟不上服务端的发送速度的时候,消息就会堆积

问题
1:业务系统上下游的能力不匹配,造成堆积。
2.业务系统对消息的实时性要求高,短暂的堆积也无法接受。

阶段1:拉去消息:
1.客户端通过轮询从broker里面获取消息,放到本地缓存队列,这个阶段一般不会有性能问题
2.客户端把消息给业务系统去消费,就是把消息推送到消费系统里面,这时候的性能就取决于业务系统的性能了。

所以:消息堆积的问题主要在于:本地客户端的消费能力:即消费耗时和消费并发。
其中消费耗时优先级别高。

-- 消费耗时:--
影响消费耗时的逻辑其实就是:CPU、内存、IO,
比如以前消费一个消息是20ms,在活动的时候:结果变为200ms,这时候就会出现消息堆积了,因为消费速度大大降低了,这时候就需要我们大幅度提升dubbo的服务性能。

-- 消费并发--
绝大部分消费行为属于IO密集型的,即可能操作数据库,或者调用RPC,这类的消费熟读其实是在于后端的数据库或者外系统的吞吐量,通过增加消费并行度,可以提高消费的吞吐量,但是并行度增加到一定程度,反而会下降

所以必要的合理的并行度,

1.同一个comsumerGroup下通过增加consumer实例数量来提高并行度(超过订阅队列数的consumer实例是无效的)可以通过加机器,或者已有机器启动多个线程。

2.提高单个consumer实例消费并行线程,通过修改参数consumerThreadMin .ConsumeThreadMax实现。

所以对于消息堆积,我们要明白到低是哪个环节出了问题,然后对症下药。
1.首先看一下消费耗时间。
2.当确定好耗时后,可以根据耗时大小来采取不同的措施。

---耗时较长---

1.要看一下客户端的jvm堆栈信息排查具体的业务,并且优化消费逻辑。
2.查看到耗时间正常:就需要看看并发度不够,导致的消息堆积,需要逐步扩大消费线程或者扩容节点来解决。

查看客户端jvm的堆栈:
假如消费耗时非常高,需要查看Consumer实例JVM的堆栈
ps -ef|grep java 获取正在运行的Java程序,通过启动主类获取对应的进程ID

jstack pid > stack.log获取线程的堆栈
执行以下命令:查看ConsumerMessageThread 的信息。
1.空闲无堆积的堆栈:消费空闲的情况,消费线程都会处于waiting状态,,等待从消费任务中获取消息。
2.消费逻辑抢锁休眠等:消费线程阻塞在一个睡眠等待上,导致消费缓慢
3.消费线程阻塞在外部的HTTP调用上,导致消费缓慢。

总结:
push模式启动后:分为两个阶段:拉取消息和消费消息。

消费堆积主要的原因就是在于:消费耗时和消费并发度。

首先分析消费耗时:然后根据耗大小采取不同的措施。
若排查到耗时长:查看堆栈信息,排查具体的业务逻辑,并优化消费逻辑。
若排查到耗时正常:则有可能是并发度不够导致堆积,需要逐步扩大消费线程和扩容节点来解决问题。

posted on 2025-08-15 20:30  cherry小樱桃  阅读(14)  评论(0)    收藏  举报