一、背景
我们在日常工作中,经常会碰到线上告警,消息队列消息积压了,试想如果对消息的消费速率有要求的场景,消息积压一定会或多或少对自己本身的业务场景有影响,这里就针对消息积压的场景,谈谈具体的排查思路以及解决方式
二、案例分析
由于在公司使用的kafka的场景会比较多,所以下面就以Kafka的场景进行分析,其他消息中间件的排查思路以及解决方式类似,可以举一反三。
(1)消息堆积感知
我们一般知道消息堆积一般是通过监控告警得知,或者用户反馈什么场景怎么这么久还没计算出来,这个时候我们就得警惕了,回想这个场景是不是使用消息队列进行实现,是不是有可能消息堆积导致。
分享最近的案例,我们会用变更日志记录用户或者系统的一些操作,记录变更日志是通过消息队列(Kafka)进行实现,如下图所示
产品反馈具体某个业务场景,明明已经执行过了,但是还是没有看到变更日志记录,当时我的第一反应就是会不会消息积压了,通过查看消息监控,消息果然积压了。
(2)消息积压排查思路
消息积压也分类型,下面我对自己遇到过的场景进行归类
场景一、生产者消息量本身就是这么大,消费者消费速度跟不上消息的生产速度(较严重,如果不提升消费能力,消息积压会越来越严重,这种属于上线之前对生产者的生产能力和消费者的消费能力评估不到位导致)
场景二、业务高峰期,消息瞬时增大,原本生产者和消费者是保持平衡(或者消费能力略大于生产能力),但是由于生产者的消息量在某个时间段激增,导致消息积压。
场景三、原本生产者生产消息数量和消费者消费消息数量持平,但是经过一段时间的业务发展,消费者渐渐乏力,导致了消息积压(需处理)
(3)解决方案
针对上面的场景,其实本质上就是提升消费能力,消费能力提升后,消费的消息就多了,积压的消息就自然减少了。
解决方案总结:
1、首先我们得明确消息队列本来就是用来异步、解耦、削峰,先评估是否对业务有影响,如果没影响是否可以慢慢消费,不进行处理。
2、增加消息队列分区,这种情况适用于生产节点较多,例如生产有20个节点,消息队列分区数是6个,这个时候其实有些节点是没有进行消费的,可以将分区数扩大到12或者16,让更多节点参与消费,增大消费能力。但需注意分区扩充后就无法再进行缩小。
3、紧急排查代码是哪里有严重阻碍拖慢整个消费者消费能力的逻辑,改造消费者逻辑,将耗时逻辑进行优化,可以用上我们常用的缓存技术、异步化处理,并发处理等等,具体场景需具体分析,将这段逻辑进行优化,提升我们消费者的消费速度,消费速度快了,消费能力自然就上去了,积压的消息自然就会减少。
具体解决方案:
回到刚才说到我遇到的日志系统消息积压的问题,我通过观察发现生产环境消息队列的分区数只有2个,但实际生产有14个节点,应该是业务发展,更多的业务场景接入了日志系统,导致消费者的消费能力渐渐跟不上生产者的生产能力,所以我选择增加分区,分区数增加到8,让更多的节点参与消费,即解决了这个问题,后续观察消费者的消费能力是大于生产者的生产能力,不会再产生消息堆积。
三、总结
针对消息积压的场景,我们的解决思路的大方向一定是围绕提升消费能力的方向去处理,在现实生活中,就像银行办理业务的原理一样,如果每天都是排长队,要么是新开窗口,让更多的窗口帮助人们办理业务,或者引流到其他银行分行进行处理,本质上都是提升单位时间处理业务的能力。所以我们再解决消息积压的方向也是要围绕这个点进行处理。