深色模式
消息积压排查
摘要:积压的根因通常是"消费能力下降"而非"生产变多"。本文先量化 lag 的增长趋势,再从消费者存活、并行度、单条耗时三个维度定位,最后说明 rebalance 风暴这一隐蔽成因。
适用环境
bash
kafka-consumer-groups.sh --version 2>/dev/null
rabbitmqctl status 2>/dev/null | head -51
2
2
排障步骤
第 1 步:量化积压程度与趋势
Kafka:
bash
kafka-consumer-groups.sh --bootstrap-server <broker>:9092 \
--describe --group <group-id>1
2
2
看 LAG 列以及 CURRENT-OFFSET 是否在增长。lag 不涨但也不降,说明消费者已停止消费。
RabbitMQ:
bash
rabbitmqctl list_queues name messages messages_ready messages_unacknowledged consumers1
第 2 步:确认消费者是否活着
bash
kafka-consumer-groups.sh --bootstrap-server <broker>:9092 \
--describe --group <group-id> --members --verbose
rabbitmqctl list_consumers1
2
3
2
3
消费者数为 0 或成员缺失,说明消费者进程已退出或网络断开,这是最常见的积压原因。
第 3 步:检查并行度是否用满
bash
kafka-topics.sh --bootstrap-server <broker>:9092 --describe --topic <topic> | head -51
消费者数超过分区数时多余的消费者闲置
一个分区只能被组内一个消费者消费。分区数 4 而消费者 8 个,实际只有 4 个在工作,扩容消费者无效。
第 4 步:判断是吞吐低还是单条慢
bash
# 观察消费端日志中的单条处理耗时
grep -iE 'process|consume|handle' /var/log/app/app.log | tail -501
2
2
如果单条处理耗时从 10ms 涨到 500ms(常见于下游依赖变慢),扩容分区收益有限,应先修下游。
第 5 步:检查 rebalance 是否频繁发生
bash
grep -iE 'rebalance|revocation|Max poll interval' /var/log/app/app.log | tail -301
max.poll.interval.ms 超时会引发反复 rebalance
单批处理时间超过 max.poll.interval.ms,消费者被踢出组并触发 rebalance,期间整个组停止消费,积压反而加速。应调大该参数或减小 max.poll.records。
第 6 步:RabbitMQ 侧重点看 unacked
bash
rabbitmqctl list_queues name messages_unacknowledged consumers
rabbitmqctl list_consumers -q1
2
2
messages_unacknowledged 持续高说明消费者拿到消息但没 ack,通常是处理卡住或 prefetch 设置过大。
第 7 步:处置
bash
# Kafka 提高并行度(分区数只能增加不能减少)
kafka-topics.sh --bootstrap-server <broker>:9092 --alter \
--topic <topic> --partitions 161
2
3
2
3
增加分区会影响按 key 的顺序性
按 key 分区的消息在分区数变化后,相同 key 可能落到不同分区,顺序保证被破坏。
验证
bash
kafka-consumer-groups.sh --bootstrap-server <broker>:9092 --describe --group <group-id>
rabbitmqctl list_queues name messages messages_ready messages_unacknowledged1
2
2
常见坑
只看总 lag 不够
lag 总量可能稳定,但集中在某一个分区(数据倾斜),实际是单个消费者卡住。
消费者在跑但 lag 不降
可能是消费后未提交 offset,或消费逻辑进入死循环/异常重试,需看消费端日志而非只看 lag。
盲目扩容消费者
分区数不足或下游慢时,扩容只会增加 rebalance 次数,反而更慢。
直接删除 topic 或清空队列"解决积压"
会造成不可逆的数据丢失。只有在确认消息可丢弃且有备份时才可考虑,并需走审批。