使用自定义标头使用Kafka消息

时间:2019-03-15 13:50:42

标签: java spring-cloud-stream spring-kafka

我正在尝试使用Spring Cloud Stream创建一个kafka使用者,以便收听带有自定义标头( operationType )的在任何Spring上下文外部构建的Kafka消息。

我正在使用Spring Boot 1.5.x / Spring Cloud Egdware.SR5和1.1.1版本的kafka-client和kafka_2.11。

我的侦听器类包含此方法

@StreamListener(value = "dataset-changed", condition = "headers['operationType']=='UPDATE'")
public void onEvent(@Payload DatasetChangedMessage payload) {
  // my code should be execute only if the header operationType == UPDATE
}

Spring Cloud Stream配置为

spring.cloud.stream:
  bindings:
    dataset-changed:
      group: preparation
      content-type: application/json
      destination: dataset-changed
      consumer:
        headerMode: raw
        configuration:
          key.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
          value.deserializer: org.apache.kafka.common.serialization.StringDeserializer

生产者是带有kafka-client:1.1.1库的简单Java文档

Properties producerConfig = new Properties();
producerConfig.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
producerConfig.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.ByteArraySerializer");
producerConfig.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

KafkaProducer<byte[], String> producer = new KafkaProducer<>(producerConfig);

// Headers (to condition the kafka listener)
final List<Header> headers = new ArrayList<>();
headers.add(new RecordHeader("operationType", "UPDATE".getBytes()));

ProducerRecord<byte[], String> record =
        new ProducerRecord<>("dataset-changed", 0, "111".getBytes(), getJsonPayload(), headers);
Future<RecordMetadata> future = producer.send(record);
future.get();

producer.close();

当我发出kafka消息时,我会收到此类警告

2019-03-15 14:48:32.103  WARN [tdp-preparation,1e24b9764ef9bb14,1e24b9764ef9bb14,false] 34760 --- [           -L-1] .DispatchingStreamListenerMessageHandler : Cannot find a @StreamListener matching for message with id: ea27a446-69da-7b8d-1b94-50b46a40dfde

存在operationType标头

enter image description here

1 个答案:

答案 0 :(得分:0)

我相信您会因为使用headers而在消费者方面损失headerMode: raw。实际上,这意味着none-不映射标题。

考虑改用headerMode: headers

有关更多信息,请参见文档:https://cloud.spring.io/spring-cloud-stream/spring-cloud-stream.html#_consumer_properties

  

headerMode

     

设置为none时,将禁用输入的标头解析。仅对不支持本地消息头并且需要消息头嵌入的消息中间件有效。当不支持本机头时,使用非Spring Cloud Stream应用程序中的数据时,此选项很有用。设置为headers时,它将使用中间件的本机头机制。设置为embeddedHeaders时,它将标头嵌入消息有效负载中。

     

默认值:取决于活页夹的实现。