Apache kafka 卡夫卡制作人TimeoutException:1条记录过期

Apache kafka 卡夫卡制作人TimeoutException:1条记录过期,apache-kafka,kafka-consumer-api,kafka-producer-api,spring-kafka,Apache Kafka,Kafka Consumer Api,Kafka Producer Api,Spring Kafka,我将卡夫卡与弹簧靴配合使用: spring.kafka.producer.retries=0 spring.kafka.producer.batch-size=100000 spring.kafka.producer.request.timeout.ms=30000 spring.kafka.producer.linger.ms=10 spring.kafka.producer.acks=0 spring.kafka.producer.buffer-memory=33554432 spring.

我将卡夫卡与弹簧靴配合使用:

spring.kafka.producer.retries=0
spring.kafka.producer.batch-size=100000
spring.kafka.producer.request.timeout.ms=30000
spring.kafka.producer.linger.ms=10
spring.kafka.producer.acks=0
spring.kafka.producer.buffer-memory=33554432
spring.kafka.producer.max.block.ms=5000
spring.kafka.bootstrap-servers=192.168.1.161:9092,192.168.1.162:9093
卡夫卡制作人阶层

@服务
公共类MyKafkaProducer{
@自动连线
私人卡夫卡模板卡夫卡模板;
私有静态记录器Logger=LoggerFactory.getLogger(NotificationDispatcherSender.class);
//发送消息
public void sendMessage(字符串topicName,字符串消息)引发异常{
LOGGER.debug(“================主题名称=====”+topicName+”===================消息==============“+消息”);
ListenableFuture结果=kafkaTemplate.send(主题名,消息);
result.addCallback(新ListenableFutureCallback(){
@凌驾
成功时公共无效(SendResult结果){
debug(“发送的消息='{}',偏移量={}”,消息,结果.getRecordMetadata().offset());
}
@凌驾
失效时的公共无效(可丢弃的ex){
LOGGER.error(Constants.PRODUCER_MESSAGE_EXCEPTION.getValue()+“:”+ex.getMessage());
}
});
}
}
卡夫卡配置:

spring.kafka.producer.retries=0
spring.kafka.producer.batch-size=100000
spring.kafka.producer.request.timeout.ms=30000
spring.kafka.producer.linger.ms=10
spring.kafka.producer.acks=0
spring.kafka.producer.buffer-memory=33554432
spring.kafka.producer.max.block.ms=5000
spring.kafka.bootstrap-servers=192.168.1.161:9092,192.168.1.162:9093
假设我在主题
mytesttopic
中发送了10次1000条消息

10次中有8次我成功获取消费者中的所有消息,但有时我会在以下错误中获取此消息:

2017-10-05 07:24:11,[ERROR][my service-LoggingProducerListener-onError:76]发送key='null'和payload='{“deviceType”:“X”,“deviceKeys”:[{“apiKey”:“X-X-o”}],“devices…”主题为我的测试主题时引发异常


org.apache.kafka.common.errors.TimeoutException:my-test-topic-4的1条记录因批次创建加上延迟时间而过期30024毫秒有3种可能性:

  • 增加
    request.timeout.ms
    -这是Kafka等待整个批次在缓冲区中准备就绪的时间。因此,在您的情况下,如果缓冲区中的消息少于100000条,将发生超时。更多信息如下:
  • 减少批大小
  • -与上一点相关,它将更频繁地发送批,但它们包含的消息更少
  • 根据消息大小,您的网络可能无法赶上高负载?检查吞吐量是否不是瓶颈
  • 错误中的第一条线索是
    30024 ms已通过
    -配置
    spring.kafka.producer.request.timeout.ms=30000
    。这30秒的等待是为了填满producer端的缓冲区

  • 当消息发布时,它会在生产者端得到缓冲,并等待30秒(请参见上面的配置)来填充。
    spring.kafka.Producer.batch size=100000
    表示100KB,因此如果消息接收负载较低,并且缓冲区在30秒内没有填充更多消息到100KB,则您可能会看到此消息

  • spring.kafka.producer.linger.ms=10
    用于摄取负载较高的情况,并且生产者希望限制
    send()
    对kafka代理的调用。这是在批处理就绪后(即缓冲区填充到100KB的批处理大小后),生产者在向代理发送消息之前将等待的时间

  • 解决方案:

    • 增加
      linger.ms
      以在批处理就绪后保留更长时间的消息。如果需要更多时间来填充批处理,请增加
      request.timeout.ms
    • 另一种方法:减少批处理大小,或增加请求.timeout.ms,或两者兼而有之

    您描述的这个错误是来自生产者还是消费者?我在生产者身上发现了这个错误。因此,对于这样一个“低”
    请求,您的批处理速度太慢。超时。ms
    。在不足30秒的时间内,尝试将
    批处理大小降低一点?(我是卡夫卡的新手,请容忍我)我不知道,但是根据你的错误,你真的超过了30秒:
    因为30024毫秒已经过去了
    自从我在卡夫卡上启用SSL以来,我和OP有同样的问题,注意,像我一样,他也设置了
    linger.ms
    。根据文档,即使批次没有满,批次也会在这段延迟时间后发出,因此,即使批量很大,它也不应该超时。@michalbrz在阅读和理解了这两篇文章:1)和2)之后。我觉得我们应该增加批量大小以避免超时。如果我们增加批量大小->批数将减少->请求数将减少->发送记录所需的时间将减少->超时将减少不常发生