Kafka制作人TimeoutException:过期1条记录

时间:2017-10-09 15:15:18

标签: apache-kafka kafka-consumer-api kafka-producer-api spring-kafka

我正在使用Kafka与 Spring-boot:

Kafka Producer类

@Service
public class MyKafkaProducer {

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    private static Logger LOGGER = LoggerFactory.getLogger(NotificationDispatcherSender.class);

    // Send Message
    public void sendMessage(String topicName, String message) throws Exception {
        LOGGER.debug("========topic Name===== " + topicName + "=========message=======" + message);
        ListenableFuture<SendResult<String, String>> result = kafkaTemplate.send(topicName, message);
        result.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
            @Override
            public void onSuccess(SendResult<String, String> result) {
                LOGGER.debug("sent message='{}' with offset={}", message, result.getRecordMetadata().offset());
            }

            @Override
            public void onFailure(Throwable ex) {
                LOGGER.error(Constants.PRODUCER_MESSAGE_EXCEPTION.getValue() + " : " + ex.getMessage());
            }
        });
    }
}

Kafka-configuration:

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

假设我已在主题my-test-topic中发送了10次10​​00条消息。

10次中有8次我成功收到了消费者的所有邮件,但有时我收到的信息错误

2017-10-05 07:24:11, [ERROR] [my-service - LoggingProducerListener - onError:76] Exception thrown when sending a message with key='null' and payload='{"deviceType":"X","deviceKeys":[{"apiKey":"X-X-o"}],"devices...' to topic my-test-topic

org.apache.kafka.common.errors.TimeoutException: Expiring 1 record(s) for my-test-topic-4 due to 30024 ms has passed since batch creation plus linger time

3 个答案:

答案 0 :(得分:8)

有三种可能性:

  1. 增加request.timeout.ms - 这是Kafka等待整批准备在缓冲区中的时间。因此,在您的情况下,如果缓冲区中的消息少于100 000条,则会发生超时。更多信息:https://stackoverflow.com/a/34794261/2707179
  2. 降低batch-size - 与前一点相关,它会更频繁地发送批次,但它们会包含更少的消息。
  3. 根据邮件大小,您的网络可能无法赶上高负载吗?检查您的吞吐量是否不是瓶颈。

答案 1 :(得分:2)

给予acks_config="1",它将起作用

答案 2 :(得分:1)

  1. 错误中的第一个线索是 30024 ms has passed - 配置 spring.kafka.producer.request.timeout.ms=30000 是相关的。这 30 秒的等待时间用于填充 Producer 端的缓冲区。

  2. 当一条消息被发布时,它会在生产者一侧被缓冲,并且会等待 30 秒(见上面的配置)填满。 spring.kafka.producer.batch-size=100000 表示 100KB,因此如果消息摄取负载较低,并且缓冲区在 30 秒内没有填满 100KB 的更多消息,您会看到此消息。

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

解决方案:

  • 增加 linger.ms 以在批次准备好后保留更长时间的消息。如果需要更多时间来填充批次,请增加 request.timeout.ms
  • 另一种方法:减少batch-size,或增加request.timeout.ms,或两者兼而有之。