线上kafka消息堆积 , 所有consumer全部掉线,到底怎么回事?
最近处理了一次线上故障,具体故障表现就是kafka某个topic消息堆积,这个topic的相关consumer全部掉线 。
整体排查过程和事后的复盘都很有意思 , 并且结合本次故障,对kafka使用的最佳实践有了更深刻的理解 。
好了,一起来回顾下这次线上故障吧,最佳实践总结放在最后,千万不要错过 。
1、现象
- 线上kafka消息突然开始堆积
- 消费者应用反馈没有收到消息(没有处理消息的日志)
- kafka的consumer group上看没有消费者注册
- 消费者应用和kafka集群最近一周内没有代码、配置相关变更
所以我们重点放在客户端排查上 。
1)arthas在线修改日志等级,输出debug
由于客户端并没有明显异常日志 , 因此只能通过arthas修改应用日志等级,来寻找线索 。
果然有比较重要的发现:
2022-10-25 17:36:17,774 DEBUG [org.apache.kafka.clients.consumer.internals.AbstractCoordinator] - [Consumer clientId=consumer-1, groupId=xxxx] Disabling heartbeat thread2022-10-25 17:36:17,773 DEBUG [org.apache.kafka.clients.consumer.internals.AbstractCoordinator] - [Consumer clientId=consumer-1, groupId=xxxx] Sending LeaveGroup request to coordinator xxxxxx (id: 2147483644 rack: null)
看起来是kafka-client自己主动发送消息给kafka集群,进行自我驱逐了 。因此consumer都掉线了 。2)arthas查看相关线程状态变量用arthas vmtool命令进一步看下kafka-client相关线程的状态 。
文章插图
可以看到 HeartbeatThread线程状态是WAITING,Cordinator状态是UNJOINED 。
此时,结合源码看 , 大概推断是由于消费时间过长 , 导致客户端自我驱逐了 。
于是立刻尝试修改max.poll.records,减少一批拉取的消息数量,同时增大max.poll.interval.ms参数,避免由于拉取间隔时间过长导致自我驱逐 。
参数修改上线后,发现consumer确实不掉线了,但是消费一段时间后 , 还是就停止消费了 。
3、最终原因相关同学去查看了消费逻辑 , 发现了业务代码中的死循环,确认了最终原因 。
消息内容中的一个字段有新的值,触发了消费者消费逻辑的死循环,导致后续消息无法消费 。消费阻塞导致消费者自我驱逐,partition重新reblance,所有消费者逐个自我驱逐 。这里核心涉及到kafka的消费者和kafka之间的保活机制,可以简单了解一下 。
文章插图
kafka-client会有一个独立线程HeartbeatThread跟kafka集群进行定时心跳,这个线程跟lisenter无关,完全独立 。
根据debug日志显示的“Sending LeaveGroup request”信息,我们可以很容易定位到自我驱逐的逻辑 。
文章插图
HeartbeatThread线程在发送心跳前,会比较一下当前时间跟上次poll时间,一旦大于max.poll.interval.ms 参数,就会发起自我驱逐了 。
4、进一步思考虽然最后原因找到了,但是回顾下整个排查过程,其实并不顺利,主要有两点:
- kafka-client对某个消息消费超时能否有明确异常?而不是只看到自我驱逐和rebalance
- 有没有办法通过什么手段发现 消费死循环?
推荐阅读
- 天玑2000最新消息_天玑2000曝光
- 三星S22Ultra最新消息_三星S22Ultra手机曝光
- 图文全面详解 Kafka 架构和原理机制
- 英雄联盟如何在游戏里回复好友(lol快速回复别人消息)
- LOL游戏里面怎么回复好友消息(lol游戏内怎么给好友回消息)
- 10 LOL如何在游戏中回复好友消息(lol怎么在游戏里给好友回消息)
- 英雄联盟在游戏过程中如何回复好友消息(英雄联盟对局中怎么回复好友消息)
- iqoo7pro上市时间_iqoo7pro参数最新消息
- 三星zfold3最新消息_三星Galaxyzfold3上市
- 黑鲨5什么时候上市_黑鲨5手机最新消息