簡體   English   中英

為 Kafka 流配置 Serdes 的問題

[英]Issue with configuring Serdes for Kafka Streams

我將 json object 放到我的“提交”主題中。 我想使用 Kafka Streams 消費消息,但出現錯誤

@Configuration
@EnableKafka
@EnableKafkaStreams
public class AnalyzerConfiguration {
    @Bean(name = KafkaStreamsDefaultConfiguration.DEFAULT_STREAMS_CONFIG_BEAN_NAME)
    public KafkaStreamsConfiguration kStreamsConfigs() {
        Map<String, Object> props = new HashMap<>();
        props.put(StreamsConfig.APPLICATION_ID_CONFIG, "test-streams");
        props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
        props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
        props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, commitSerde().getClass());

        return new KafkaStreamsConfiguration(props);
    }

    @Bean
    public Serde<Commit> commitSerde() {
        return Serdes.serdeFrom(new JsonSerializer<>(), new JsonDeserializer<>(Commit.class));
    }

    @Bean
    public KStream<String, Commit> kStream(StreamsBuilder builder) {
        KStream<String, Commit> stream = builder.stream("commits", Consumed.with(Serdes.String(), commitSerde()));

        KTable<String, Long> commitsCount = stream
                .mapValues(Commit::getAuthorName)
                .selectKey((key, word) -> word)
                .groupByKey()
                .count(Materialized.as("Counts"));

        commitsCount.toStream().to("commits-count", Produced.with(Serdes.String(), Serdes.Long()));

        return stream;
    }
}

日志說:

Exception in thread "test-streams-469f5ee6-d0de-472e-a602-a7b6d11f2e1c-StreamThread-1" org.apache.kafka.streams.errors.StreamsException: Failed to configure value serde class org.apache.kafka.common.serialization. Serdes$WrapperSerde

原因:org.apache.kafka.common.KafkaException:找不到 org.apache.kafka.common.serialization.Serdes$WrapperSerde 的公共無參數構造函數

引起:java.lang.NoSuchMethodException

您的問題是StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG的注冊。 首先,在您的示例中不需要這樣做,因為您在創建 KStream 時使用的Consumed中指定了值 serde。 您可以省略默認的 serde。

如果您將 class 注冊為默認 serde,Kafka Streams 將在某個時候通過反射創建該 class 的實例。 這調用了 class 的默認(無參數)構造函數。 在您的示例中,將使用Serdes.serdeFrom(new JsonSerializer<>(), new JsonDeserializer<>(Commit.class)) 這個 class 沒有這樣的構造函數,導致異常。

如果你想為你的Commit類型注冊一個默認的 serde,你需要把它包裝成一個小的 class:

public class CommitSerde extends WrapperSerde<Commit> {

    public CommitSerde() {
        super(new JsonSerializer<>(), new JsonDeserializer<>(Commit.class));
    }
}

這個 class 應該適合使用props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, CommitSerde.class.getName()); 在你的例子中。

暫無
暫無

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

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