簡體   English   中英

spring-kafka - 如何從頭開始閱讀一個主題,同時從頭開始閱讀另一個主題?

[英]spring-kafka - how to read one topic from the beginning, while reading another one from the end?

我正在編寫一個 spring-kafka 應用程序,其中我需要閱讀 2 個主題:test1 和 test2:

public class Receiver {

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

    @KafkaListener(id = "bar", topicPartitions =
{ @TopicPartition(topic = "test1", partitions = { "0" }),
  @TopicPartition(topic = "test2", partitions = { "0" })})
    public void receiveMessage(String message) {
        LOGGER.info("received message='{}'", message);
    }
}

我的配置如下所示:

@Configuration
@EnableKafka
public class ReceiverConfig {

    @Value("${kafka.bootstrap.servers}")
    private String bootstrapServers;

    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> props = new HashMap<>();
        // list of host:port pairs used for establishing the initial connections
        // to the Kakfa cluster
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
                bootstrapServers);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
                IntegerDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
                StringDeserializer.class);
        // consumer groups allow a pool of processes to divide the work of
        // consuming and processing records
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "test1");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "test2");

        return props;
    }

    @Bean
    public ConsumerFactory<Integer, String> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(consumerConfigs());
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<Integer, String> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<Integer, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());

        return factory;
    }

    @Bean
    public Receiver receiver() {
        return new Receiver();
    }
}

我需要能夠僅讀取“test1”中的最新消息,同時能夠讀取“test2”開頭的所有消息。 我只對應用程序啟動時的“test2”消息感興趣,但只要應用程序正在運行,就需要不斷地閱讀“test1”消息。

有沒有辦法配置這樣的功能?

我也一直在努力解決這個問題,並想提出一個更通用的解決方案。

當您的解決方案有效時,您需要對分區進行硬編碼。 您還可以讓使用@KafkaListener的 class 實現ConsumerSeekAware接口。

這為您提供了三種可用於尋找特定偏移量的方法。 一旦分配了分區,就會調用一種方法。 所以它可能看起來像這樣。

@Override
public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
    assignments.keySet().stream()
        .filter(partition -> "MYTOPIC".equals(partition.topic()))
        .forEach(partition -> callback.seekToBeginning("MYTOPIC", partition.partition()));
}

這樣,當您決定向主題添加更多分區時,您無需接觸任何代碼:)

希望這可以幫助某人。

這是一種對我有用的方法:

@KafkaListener(id = "receiver-api",         
        topicPartitions =
        { @TopicPartition(topic = "schema.topic", 
                partitionOffsets = @PartitionOffset(partition = "0", initialOffset = "0")),
                @TopicPartition(topic = "data.topic", partitions = { "0" })})
    public void receiveMessage(String message) {
        try {
                JSONObject incomingJsonObject = new JSONObject(message); 
                if(!incomingJsonObject.isNull("data")){
                    handleSchemaMessage(incomingJsonObject);
                }

                else {
                    handleDataMessage(incomingJsonObject);
                }

        } catch (Exception e) {
            e.printStackTrace();
        }

使用“partitionOffsets”注解(import org.springframework.kafka.annotation.PartitionOffset;)

是能夠始終從頭開始閱讀特定主題的關鍵,同時像往常一樣“跟蹤”其他主題。

您可以瀏覽文檔 #4.1.7 幾種方法之一是在“最早”或“最新”上更改您的消費者屬性 auto.offset.reset:

...
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
...

然后,您可以創建任意數量的 @KafkaListener ,它將從開始讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM