如何从kafka主题一个一个地使用消息

时间:2019-01-30 14:33:24

标签: spring-boot apache-kafka spring-cloud spring-cloud-stream

我用一个分区建立了一个kafka主题。

kafka-topics --create --topic files.write --if-not-exists --zookeeper zookeeper:32181 --partitions 1 --replication-factor 1

在此主题中可能会推送许多消息。

但是我希望一个消费者(对于给定的组)逐个处理这些消息。

spring:
  application:
    name: file-consumer
  cloud:
    stream:
      kafka:
        binder:
          type: kafka
          brokers: localhost
          defaultBrokerPort: 29092
          defaultZkPort: 32181
          configuration:
            max.request.size: 300000
            max.message.bytes: 300000
        bindings:
          fileWriteBindingInput:
            consumer:
              autoCommitOffset: false
      bindings:
        fileWriteBindingInput:
          binder: kafka
          destination: files.write
          group: ${spring.application.name}
          contentType: 'text/plain'

还有Java示例代码

@StreamListener(FileBindingProcessor.INPUT_FILE_WRITE)
public void onInputMessage(Message<String> message, @Header(KafkaHeaders.ACKNOWLEDGMENT) Acknowledgment acknowledgment) {

    // I Would like here to synchronize the processing of messages one by one
    // But, If many messages are pushed to this topic (single partition), they will be processed asynchronously event if I didn't yet acknowledge the current message

    acknowledgment.acknowledge();
}

我的配置中缺少什么?

我以为,虽然消息未被确认(偏移量没有增加),但没有其他消息从同一分区被消耗。

3 个答案:

答案 0 :(得分:2)

如果启用autoCommitOffset(这是默认设置),则绑定器将已经确认每个记录。因此,到您的StreamListener时,记录已被确认。

更正:关于StreamListener的上述说法并不正确。当侦听器退出时,自动确认完成。

由于只有一个分区,因此您将以与发送到该主题分区相同的顺序获得消息。 您可以禁用autoCommitOffset,在这种情况下,可以使用手动确认。

答案 1 :(得分:1)

您可以将此使用者配置max.poll.records设置为1,默认为500

最大民意测验记录

  

一次调用poll()返回的最大记录数。

答案 2 :(得分:1)

不确认消息与停止发送下一条消息无关。

您不能将消息传递给另一个线程,以后再确认;如果要单线程处理,则必须在侦听器线程上进行所有处理。