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 端排查全景图
为了让你更直观地理解这三者的关系,我画了一张流程图:
4.5 避坑指南
最后,分享几个我踩过的坑:
- 不要只看 ERROR 日志:WARN 级别的“重试”信息同样重要。我曾经遇到一个案例,Producer 一直在重试,但重试次数耗尽后消息就丢了,而日志里只有 WARN 没有 ERROR。
- 指标要设置告警阈值:别等人反馈了才去看指标。把
record-error-rate > 0.5%和request-latency-avg > 200ms设成告警,能提前发现问题。 - 命令行工具要定期演练:别等到故障了才去学命令。我建议每个季度做一次压测,确保你的 Producer 配置能扛住峰值流量。
我的习惯:每次上线新业务,我都会先用 kafka-producer-perf-test 跑一轮压测,把结果截图保存。这样以后出了问题,就能对比“上线前 vs 上线后”的指标差异,快速定位变化点。
好了,Producer 端的排查方法就讲到这里。记住:日志是线索,指标是证据,命令行工具是验证手段。三者结合,才能把消息丢失的问题彻底揪出来。