CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Kafka 消息队列入门/课时/监控与 lag
RawBlame
课时目录12 节

Kafka 消息队列入门

  1. 01消息队列是什么
  2. 02核心概念
  3. 03Docker 运行 Kafka
  4. 04生产者
  5. 05消费者组
  6. 06Spring Kafka
  7. 07消息格式
  8. 08投递语义
  9. 09Kafka Streams 入门
  10. 10监控与 lag
  11. 11Kafka vs RabbitMQ
  12. 12综合练习

监控与 lag

consumer lag、JMX、运维直觉。

25 分钟

监控与 lag

这一课你将能做到

  1. 写出 consumer lag 的公式,说出 lag 持续升高的至少三种常见原因与对应排查动作
  2. 用 kafka-consumer-groups --describe 读出 CURRENT-OFFSET / LOG-END-OFFSET / LAG,并解释每列含义
  3. 做一次「消费 sleep 制造积压 → 恢复后 lag 回落」的实验,并写出应用侧该盯的信号清单

为什么要学

Broker 活着 ≠ 业务健康。线上最常见的 Kafka 事故剧本是:生产很快、消费跟不上 → lag 爬升 → 通知延迟从秒变分钟 → 磁盘被日志撑满 → 频繁 rebalance 恶化积压。用户看到的现象只是「邮件晚到一小时」,等你被叫起来排查时,没有 lag 数据就得从应用日志一行行捞。

lag 是 Kafka 世界里第一健康指标:它直接回答「下游还有多少没消化」。本课用 CLI 把 lag 看懂、把积压复现出来;生产环境再把这些数值接进 Prometheus/Grafana 告警(配合你已有的 Spring Boot Actuator 体系)。

人话:lag = 「日记本已经写到第几页」减去「这组读者的书签停在第几页」——差值就是欠账。

先建立图像

Partition P0 日志: .........[newest]   LOG-END-OFFSET = 1200(已写到的位置)
Consumer Group 书签:....^             CURRENT-OFFSET = 1000(已消费提交的位置)

LAG = 1200 - 1000 = 200   (还有 200 条没消化)
现象可能原因可尝试动作
单分区 lag 高热点 key / 分区倾斜查分区键,盐值/拆分
全组 lag 高整体吞吐不足、下游变慢加实例(≤分区数)、优化处理
lag 锯齿状波动频繁 rebalance查心跳超时、GC、慢处理
LAG=0 但业务仍异常消费失败被跳过 / 位点空转看处理错误率与死信

跟着做

步骤 1:让组跑起来

按前课跑一个 group.id=coderoadmap-notify-lab 的消费者(Java demo 或 @KafkaListener),并对 Topic 持续生产几条,确认链路通。

步骤 2:describe 读表

docker exec kafka-lab /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group coderoadmap-notify-lab

应看到类似输出(列从左到右):

GROUP                   TOPIC                        PARTITION  CURRENT-OFFSET  LOG-END-OFFSET  LAG  CONSUMER-ID   HOST        CLIENT-ID
coderoadmap-notify-lab  coderoadmap.order-events     0          12              12              0    consumer-1    /127.0.0.1  ...
coderoadmap-notify-lab  coderoadmap.order-events     1          -               3               3    -             -           -

把一行抄进笔记,逐列用中文标注:GROUP(哪个组)、PARTITION(哪个分区)、CURRENT-OFFSET(书签)、LOG-END-OFFSET(书写位置)、LAG(欠账)、CONSUMER-ID(谁在管;为空 = 没人管)。注意:--describe 不带 --group 会列出所有组。

步骤 3:制造 lag

在消费处理里临时加:

// 实验:故意拖慢消费,观察 LAG 上升(切勿带进生产)
Thread.sleep(5000);
handle(payload);

同时用 console producer 或 Java 快速发 20 条,再执行步骤 2 的 describe。应看到:LAG 明显变大(3 分区、单实例、每条 5 秒,20 条要近百秒才能追完)。

步骤 4:恢复并观察回落

去掉 sleep,让消费者全力追赶,隔 10 秒 describe 一次。应看到:LAG 逐次下降趋近 0。若生产端仍高速写入,LAG 会稳定在某一水位波动——这说明吞吐刚好持平,也值得记录。

步骤 5:验证「加实例」的效果

先 Ctrl+C 让消费者全部退出,然后只起 1 个实例(3 分区一人扛),快速发 30 条;再补起第 2 个同组实例,describe 观察 CONSUMER-ID 列:分区重新分配、追赶速度近乎翻倍。这就是「扩展上限 = 分区数」的实操版。

步骤 6:应用侧指标入口(概念)

# Spring Boot Actuator / Micrometer 打标
management:
  endpoints:
    web:
      exposure:
        include: health,prometheus
  metrics:
    tags:
      application: coderoadmap-api

生产清单:应用侧看监听器处理耗时、失败计数(kafka_listener_seconds / errors);集群侧用 Kafka Exporter 暴露 kafka_consumergroup_lag 到 Prometheus,Grafana 画 lag 曲线。与 Redis 监控(命中率、慢命令)不同:Kafka 健康叙事的中心是积压与再平衡。

讲清楚要点

  1. 因为LAG = LOG-END-OFFSET − CURRENT-OFFSET,所以它是消费落后量的直接度量,是第一告警候选。
  2. 因为追平后 LAG≈0 也可能是「两端都停了」,所以判断健康要结合生产速率与业务延迟(消息从产生到处理完的耗时),而不是只盯绝对值。
  3. 因为热点 key 会打满单分区,所以「总实例很多但单分区 lag 爆」先查分区键分布,而不是盲目加机器——机器救不了倾斜。
  4. 因为消费者数超过分区数无效,所以扩容顺序永远是:先优化处理耗时 → 加实例到分区数 → 再考虑加分区。
  5. 因为rebalance 会整组暂停消费,所以频繁平衡本身造成假性 lag 尖峰;先看 rebalance 频率再解读 lag 曲线。
  6. 因为位点前进 ≠ 业务成功,所以要同时盯「失败计数/死信量」:位点在走、错误率飙升,LAG 好看但业务全挂。

你可能会懵的地方

  1. 「LAG=0 就一定健康?」 不一定。生产也停了、消费全失败但位点照常推进(取决于提交策略),都能让 LAG 归零。搭配生产速率指标与错误率一起看。

  2. 「为什么只有某个分区 lag 高?」 该分区的 key 有热点(大客户、固定字符串 key 全打一个分区)。查 --describe 里该分区对应 CONSUMER-ID 的处理耗时,回生产者侧改 key 策略。

  3. 「describe 里 CONSUMER-ID 是空的?」 该分区没有活着的消费者(进程退了、或组只剩位点没有成员)。空组也能显示 LAG,但那是「欠账没人还」。先确认进程在线。

  4. 「和 MySQL 慢查询什么关系?」 消费里同步写库时二者耦合:慢查询拖慢消费 → lag 上涨。用「listener 处理耗时」指标把两层拆开:处理慢 → 修 SQL;处理快但 lag 高 → 修并行度。

  5. 「告警阈值设多少?」 不要「LAG>0 就报警」(微延迟是常态)。按持续时长 + 绝对量 + 增长趋势:如「lag > 10000 且持续 5 分钟」或「lag 每分钟净增 > 1000」。核心是捕捉「追不上」的趋势,不是瞬时波动。

错法对照

错法问题正解
只看 Broker CPU,不看 consumer lagBroker 空闲但下游积压成灾组 LAG 纳入常规巡检/大屏
lag 高就无脑加到 30 个消费者(3 分区)超出分区数的实例全空转先加到 ≤ 分区数,再评估加分区
处理里同步调 10s 慢 HTTP 还怪 Kafka消费被下游拖死异步化/优化处理,监控 listener 耗时
告警「LAG>0 立刻打电话」瞬时波动制造告警疲劳持续时长 + 绝对阈值 + 增长趋势
LAG=0 就宣布恢复可能两端都停/全在报错结合生产速率与失败率判断

卡点急救

  1. describe 报 Consumer group ... does not exist:组还没有任何成员提交过位点(从没跑过消费者)。先起消费者跑一轮,或确认组名拼写。
  2. LAG 高但看不出谁在消费:CONSUMER-ID 为空 → 消费者死了或卡在 rebalance。查应用日志(rebalance 关键字)、GC 日志,必要时重启实例观察重新入组。
  3. 磁盘被撑爆:Topic retention 过长或生产暴涨。临时:扩磁盘 + 清理过期段(retention.ms);长期:按流量规划保留策略与容量告警(磁盘使用率 80% 预警)。

面试常问

  • 什么是 consumer lag?怎么监控和治理? LAG = LOG-END-OFFSET(分区最新位点)− CURRENT-OFFSET(组已提交位点),即未消费量。监控:kafka-consumer-groups --describe 手动看,或 Kafka Exporter + Prometheus 持续采集 kafka_consumergroup_lag。治理三板斧:优化消费逻辑耗时(先做)→ 扩实例到分区数上限 → 扩分区;同时查热点 key 与下游依赖(DB/HTTP)是否拖慢。

  • 你怎么设计 Kafka 的告警? 分层:①积压类——组 LAG 超阈值且持续 N 分钟、或净增速率为正且超速;②错误类——消费失败率、死信 Topic 新增消息;③基础设施——Broker 存活数、磁盘使用率、ISR 收缩(UnderReplicatedPartitions>0);④业务端到端——事件产生到处理完成的延迟 SLO。避免单点瞬时阈值制造告警疲劳。

  • UnderReplicatedPartitions 指标说明什么? 有分区的副本落后于 Leader 不在 ISR 里。可能原因:某 Broker 负载高/磁盘慢/网络抖动/Broker 宕机。它是集群健康的关键指标:URP 持续 > 0 说明副本冗余正在失效,此时再挂一台就可能丢数据或不可用。

自测三问

  1. 用自己的话写 LAG 公式,并解释 CURRENT-OFFSET 与 LOG-END-OFFSET 分别是谁的位置。
  2. 处理里 sleep 5s + 快发 20 条后,LAG 应如何变化?恢复后呢?
  3. 单分区 lag 高与全组 lag 高:排查顺序有何不同?

小结一句话

Lag 是消费健康的晴雨表:会 describe --group 读三列位点、会复现积压与回落、会分层设计告警,监控入门即过关。

延伸

  • Kafka 官方文档 — 消费组运维与 lag
  • 下一课「Kafka vs RabbitMQ」:收下这套能力后,回到选型视角——什么时候该用谁。
加载本节练习…
← 上一课Kafka Streams 入门下一课 →Kafka vs RabbitMQ