一、背景
某一天下午业务高峰期,突然收到系统告警,kafka对应的topic消息出现大量积压,且kafka消费速率和写入速率无明显变化,
-
5分钟内主题平均每分钟写入速率如下:当前 419718,昨天 366523,对比昨天增长14.51%
-
5分钟内平均每分钟消费速率如下:当前 348716,昨天70522,对此昨天降低589%,当前积压 1252965,消费速率已低于写入速率,积压量持续增长
二、问题排查
从这个告警消息可以看出,我们xx模块消费kafka对应的topic消息出现大量积压,导致消息积压的原因:
-
1、生产消息过快
-
2、消费速率过慢
一般我们可以检查消费端日志,是否有大量报错,另外通过监控系统的dump文件,查看耗时比较久的线程,有针对性优化代码:比如上面的报警后面发现,采用hutool组件的JSONUtil.toLst()方法,这个方法在高并发下性能非常差。
三、解决方案
-
消费端:
-
优先扩节点(应急处理)
如果 应用消费节点 小于 kafka partiton分区数,可以扩应用消费节点,否则,扩应用消费节点没用;
例如:dance-member-service应用节点: 24个,broker分区数: 16,扩应用节点是否有用?—— 答案: 没用 dance-member-service应用节点: 12个,broker分区数: 16,扩应用节点是否有用? ——答案:有用,扩4个节点,消费能力明显增强
-
优化消费端代码 自动提交改为手动提交; 单条消费消息改为批量消费消息,数据单条入库改为批量入库; 消费逻辑涉及DB操作,第一时间检查是否有慢SQL(MySQL Explain详解);
系统不能快速扩容的话,采用动态开关降级,不入库或者不做业务处理,直接快速消费;
-
-
broker端:
优先扩节点(应急处理)
如果kafka partition分区数 小于 应用消费节点,可以扩broker分区数,否则,扩broker分区数没用;
例如:dance-member-service应用节点: 12个,broker分区数: 16,扩broker分区数是否有用? ——答案: 没用
dance-member-service应用节点: 24个,broker分区数: 16,扩broker分区数是否有用?—— 答案:有用,有8个应用节点处于空闲状态,扩8个节点,消费能力明显增强
-
生产端:
-
系统不能快速扩容的话,针对生产端采用动态配置开关降级,关闭MQ生产;
-
消费端消息没有积压后,通过消息补偿机制对业务消息补偿,同时消费端需要支持幂等
四、节假日大促相关预案
双十一大促或者节假日做活动抢购,这个时候生产端的消息一定会大大增加,很容易就会消息积压。我们平时要做好链路压测,尽可能优化消费端代码,提高消费速率。同时准备大促前的相关预案:
-
支持动态扩容
-
配置开关动态关闭生成端
-
配置开关动态关闭消费端
-
生成端支持消息补偿
-
消费端支持消息幂等
-
网友评论