现象
生产者抛出 TimeoutException: Expiring 1 record(s) for orders-0: 30000 ms has passed since batch creation,或 Topic orders not present in metadata after 60000 ms;开发环境正常,压测时超时;生产吞吐骤降但消费 lag 并不高。
诊断
先确认主题与分区领导节点:
kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic orders
kafka-topics.sh --bootstrap-server localhost:9092 \
--describe --under-replicated-partitions
主题不存在或分区没有 leader 会直接导致元数据超时;若 ISR 小于 min.insync.replicas,acks=all 永远无法成功,磁盘写满的 broker 常表现成这样。再用控制台生产者验证链路:
kafka-console-producer.sh --bootstrap-server localhost:9092 --topic orders \
--producer-property acks=all --producer-property delivery.timeout.ms=10000
立即报错说明 broker 侧拒绝,一直挂到超时则更像网络不可达、元数据失败或请求队列饱和。最后用 kafka-producer-perf-test.sh 对比平均与最大延迟,判断是否存在 broker 限流或重试放大。
修复
把 delivery.timeout.ms 设为明显大于 linger.ms + request.timeout.ms + 重试退避 的值,低延迟场景降低 linger.ms,保持 acks=all 并修复 ISR;恢复 broker 磁盘与负载,复用单个长生命周期生产者,并开启幂等避免重试重复写入:
acks=all
enable.idempotence=true
linger.ms=20
request.timeout.ms=30000
delivery.timeout.ms=120000
验证
以生产参数重跑 perf test,确认最大延迟低于 delivery.timeout.ms 且过期记录为零;重启一个 broker 时观察 record-error-rate 能回落到 0,under-replicated 分区清空,消费者侧每条订单只出现一次,说明超时重试没有造成重复。