Kafka生产者挂起,发送消息出现批量过期超时异常该如何解决?
Kafka生产者批量消息超时异常解决指南
异常本质说明
你遇到的org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for save-request-0:604351 ms has passed since batch creation异常,属于Kafka生产者核心报错类型:消息被存入生产者本地的待发送批次后,超过了配置的最大等待时长仍未成功发送到Broker端,被生产者主动标记为发送失败。
可行排查&解决思路
1. 先确认基础网络&集群状态
- 验证生产者所在服务器到Kafka集群所有Broker的监听端口连通性:在应用服务器执行
telnet BrokerIP 端口或nc -zv BrokerIP 端口 - 检查防火墙、安全组规则,确认没有拦截生产者到Broker的出站请求、Broker到生产者的响应请求
- 执行
kafka-topics.sh --describe --topic save-request --bootstrap-server Broker地址:端口查看报错Topic的分区状态,确认没有离线分区、副本不同步的问题 - 排查Broker节点的负载:确认Broker的CPU、内存、磁盘IO没有持续跑满,磁盘使用率没有超过85%的阈值
2. 调整生产者核心配置
你的单条消息大小为60KB,远大于Kafka默认的16KB批次大小,重点调整以下参数:
# 消息发送最大超时时间,默认30秒,你报错时已经等待600秒仍失败,建议调整为120000(2分钟) spring.kafka.producer.properties.delivery.timeout.ms=120000 # 批次大小默认16KB,你的单条消息60KB已经超过默认值,建议调整为131072(128KB) spring.kafka.producer.batch-size=131072 # 批次空闲等待时间,默认0,建议调整为20ms,给批次留足够时间聚合消息再发送 spring.kafka.producer.properties.linger.ms=20 # 生产者本地发送缓冲区大小,默认32MB,建议调整为67108864(64MB)避免缓冲区满阻塞 spring.kafka.producer.buffer-memory=67108864 # 单请求超时时间,必须小于delivery.timeout.ms,建议调整为60000(1分钟) spring.kafka.producer.properties.request.timeout.ms=60000 # 单条消息最大允许大小,默认1MB,可根据后续业务调整为5242880(5MB) spring.kafka.producer.properties.max.request.size=5242880 # 确认机制,业务允许低一致性的话可设置为1,仅需Leader副本确认就返回成功,降低超时概率;要求高一致性保留all即可 spring.kafka.producer.acks=1 # 发送失败重试次数,建议设置为3次,重试间隔1秒 spring.kafka.producer.retries=3 spring.kafka.producer.properties.retry.backoff.ms=1000
3. 调整Broker端配置
- 确认Broker端
message.max.bytes参数不小于生产者配置的max.request.size,默认值1MB可以满足你的60KB消息需求,如果集群之前有调小过该参数需要调整对齐 - 确认Broker端
replica.fetch.max.bytes参数不小于message.max.bytes,避免副本同步失败导致ISR列表异常
4. 代码逻辑排查
- 不要在业务主线程直接调用同步发送方法
kafkaTemplate.send(...).get(),建议放到独立异步线程池执行,避免业务线程阻塞导致消息堆积在本地批次 - 通过JMX监控
kafka.producer:type=producer-metrics,client-id=xxx下的record-queue-time-avg指标,确认消息在本地队列的平均等待时间是否过高 - 确认发送消息的回调逻辑没有阻塞生产者的网络发送线程
内容的提问来源于stack exchange,提问作者user2285606
相关产品推荐
相关产品推荐

