已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
Kafka 3.5(KRaft,3 broker),topic order-settle 24 分区,消费组 8 实例(每实例 3 分区),max.poll.interval.ms=300000(5min),session.timeout.ms=10000,CooperativeStickyAssignor + static membership。消费逻辑:poll → 逐条调下游账务 RPC 落库(单条 P50≈80ms,P99 平时≈800ms),at-least-once + 业务幂等表(PG 唯一索引)。
上个月两次线上事故,模式完全一样:下游账务库一次慢查询风暴,单条处理时间从 800ms 涨到 15s+,单实例一次 poll 拉了 500 条就处理了 3 分钟,逼近 5 分钟上限。第一次实例真的被踢出 → 整组 cooperative rebalance → 其他 7 个实例各丢 0~2 个分区重新分配 → 幂等表兜住了但多花了 40s 全组停顿;第二次提前手动 kill 了慢实例,同样触发 rebalance。
事后复盘我们的告警链路:
consumer-group-lag(Prometheus 指标 kafka_consumergroup_lag),阈值设 10000。问题是 lag 是「组级滞后量」,单实例慢了 2 分钟 lag 可能才涨 3000(其他 7 个实例还在正常消费),到 lag 破阈值时慢实例往往已经被踢了——滞后指标对「单实例即将超时」没有提前量。poll() 后的处理循环加了一个 processing_ms 的 histogram(Micrometer),但只做了 P99 看板,没设告警,且没有按「距离 max.poll.interval.ms 的余量」这个维度建模;Rebalance in progress,broker 侧没有「还有 X 秒超时」的预警信号(这个我确认过,session 心跳和 poll 间隔是两个独立计时器,broker 对 poll 超时没有 grace 通知);max.poll.interval.ms 从 5min 拉到 10min,但这只会让「被踢」延迟,rebalance 风暴照样发生,治标不治本。max.poll.interval.ms - (now - lastPollReturnTime) 还是别的口径?阈值定在 50% 还是 30% 才既有提前量又不误报(正常 P99 抖动)?kafka_consumergroup_current_offset - kafka_consumergroup_committed_offset 按 partition 粒度拆到实例?pause() 慢分区或提前 commit 当前 offset(牺牲 at-least-once 的尾部几条换组级稳定),这个做法你们踩过坑吗?幂等表能兜住多少?session.timeout.ms 的倍数)你们实际量过是多少?这个窗口内实例自己 seek 回原位能不能避免重复消费?我这边 processing_ms histogram 的采集代码和两次事故的 timeline 日志都有,需要细节可以追问我。