4. Producer 端排查方法:日志、指标与命令行工具

消息丢失的排查,我一般习惯从 Producer 端开始。为什么?因为大部分丢失问题,根源都在发送端。你想想看,如果消息压根没发出去,或者发出去但没确认,那后面 Broker 和 Consumer 再怎么折腾也找不回来。

这一章,我们就聚焦 Producer 侧。我会带你从三个维度入手:日志、监控指标、命令行工具。这三板斧砍下去,80% 的发送端问题都能现出原形。

4.1 查看 Producer 日志:第一道防线

日志是最直接的证据。我在项目中遇到过好几次,开发同学说“消息丢了”,结果一查日志,发现是配置写错了,或者网络超时了。

Producer 的日志级别,我建议至少开到 WARN。如果正在排查问题,直接开到 DEBUG 也不过分。关键要关注以下几类信息:

  • ERROR 级别:发送失败、连接断开、认证失败。这些是硬伤,必须处理。
  • WARN 级别:重试次数过多、Leader 切换、元数据更新失败。这些是软伤,积累多了也会丢消息。
  • INFO 级别:连接建立、分区分配。正常信息,但能帮你确认 Producer 是否正常工作。

核心排查点:搜索日志中的 Expiring 1 record(s) 或 Failed to send 关键字。一旦出现,说明有消息已经超时并被丢弃了。

举个例子,你可能会看到这样的日志:

2025-03-15 10:23:45 ERROR [Producer client] Failed to send record to topic test-topic: 
org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for test-topic-0: 
120000 ms has passed since batch creation

这条日志说明什么?消息在缓冲区里等了 2 分钟,最终还是超时了。嗯,这里要注意:delivery.timeout.ms 默认是 120 秒,如果你的业务对延迟敏感,这个值可能太大了;但如果网络不稳定,这个值又可能太小。

4.2 监控指标:用数据说话

光看日志还不够。日志是“点”,指标是“面”。我习惯把 Producer 的 JMX 指标接入 Prometheus + Grafana,实时盯着几个关键指标。

下面这张表,是我在项目中总结的“必看指标清单”:

指标名称 含义 正常范围 异常信号
request-latency-avg 请求平均延迟(毫秒) < 50ms > 200ms 持续上升
record-error-rate 发送错误率 < 0.1% > 1% 或持续增长
record-queue-time-avg 消息在队列中平均等待时间 < 10ms > 100ms 说明积压严重
buffer-available-bytes 缓冲区剩余字节 > 总 buffer 的 20% 接近 0,说明发送跟不上生产
record-send-rate 每秒发送消息数 与业务预期一致 突然下降或剧烈波动

我的经验:request-latency-avg 突然飙升,通常不是 Producer 的问题,而是 Broker 端负载过高或网络抖动。这时候别光盯着 Producer 调优,去查查 Broker 的 CPU 和磁盘 IO。

还有一个容易被忽略的指标:record-queue-time-avg。我曾经遇到一个案例,业务方说消息丢了,但错误率是 0。后来一看这个指标,发现消息在队列里平均等了 3 秒才发出去。为什么?因为 linger.ms 设成了 5000,而且 batch.size 设得太大,小流量下消息攒不够一批,就一直等。最后虽然没报错,但延迟已经不可接受了。

4.3 使用 Kafka 自带命令行工具

命令行工具是最后的杀手锏。当日志和指标都看不出问题时,我会直接上工具验证。

4.3.1 用 kafka-console-producer 做对比测试

这个工具能帮你排除代码层面的问题。操作很简单:

# 启动一个控制台生产者,发送几条测试消息
kafka-console-producer.sh \
  --bootstrap-server localhost:9092 \
  --topic test-topic \
  --producer-property acks=all \
  --producer-property retries=5

如果控制台生产者能正常发送,而你的代码不行,那问题大概率出在代码逻辑或配置上。如果控制台生产者也不行,那就要怀疑网络、Broker 或 Topic 本身了。

注意:控制台生产者默认使用 acks=1,测试时建议显式指定 acks=all,这样才能模拟生产环境的可靠性要求。

4.3.2 用 kafka-producer-perf-test 做压力测试

这个工具能帮你评估 Producer 的吞吐量和延迟。我一般用它来做基准测试:

kafka-producer-perf-test.sh \
  --topic test-topic \
  --num-records 100000 \
  --record-size 1024 \
  --throughput 10000 \
  --producer-props bootstrap.servers=localhost:9092 acks=all

输出结果会告诉你:

  • 实际吞吐量(records/sec)
  • 平均延迟(ms)
  • 最大延迟(ms)
  • 50th/99th/99.9th 百分位延迟

如果压测结果远低于你的业务需求,那就要考虑调整 batch.size、linger.ms、compression.type 等参数了。

4.3.3 用 kafka-dump-log 验证消息是否真的到了 Broker

这是最底层的验证手段。直接查看 Broker 上的日志文件,确认消息是否被持久化:

kafka-dump-log.sh \
  --files /data/kafka/test-topic-0/00000000000000000000.log \
  --print-data-log

输出会显示每条消息的 offset、timestamp、key 和 value。如果你在 Producer 端发送了消息,但在这个日志文件里找不到,那说明消息根本没到达 Broker。这时候,问题就出在网络或 Producer 配置上了。

4.4 知识体系:Producer 端排查全景图

为了让你更直观地理解这三者的关系,我画了一张流程图:

Producer 端消息丢失排查流程 发现消息丢失 ① 查看日志 ② 监控指标 ③ 命令行工具 搜索 ERROR / WARN 关键字 检查 TimeoutException 确认重试次数与间隔 request-latency-avg record-error-rate buffer-available-bytes kafka-console-producer kafka-producer-perf-test kafka-dump-log 定位根因 → 制定修复方案 建议按 日志 → 指标 → 命令行 的顺序排查,每一步都能缩小问题范围

4.5 避坑指南

最后,分享几个我踩过的坑:

  • 不要只看 ERROR 日志:WARN 级别的“重试”信息同样重要。我曾经遇到一个案例,Producer 一直在重试,但重试次数耗尽后消息就丢了,而日志里只有 WARN 没有 ERROR。
  • 指标要设置告警阈值:别等人反馈了才去看指标。把 record-error-rate > 0.5% 和 request-latency-avg > 200ms 设成告警,能提前发现问题。
  • 命令行工具要定期演练:别等到故障了才去学命令。我建议每个季度做一次压测,确保你的 Producer 配置能扛住峰值流量。

我的习惯:每次上线新业务,我都会先用 kafka-producer-perf-test 跑一轮压测,把结果截图保存。这样以后出了问题,就能对比“上线前 vs 上线后”的指标差异,快速定位变化点。

好了,Producer 端的排查方法就讲到这里。记住:日志是线索,指标是证据,命令行工具是验证手段。三者结合,才能把消息丢失的问题彻底揪出来。