Regex 过滤卡夫卡信息的最佳方式是什么

Regex 过滤卡夫卡信息的最佳方式是什么,regex,apache-kafka,kafka-consumer-api,spring-kafka,Regex,Apache Kafka,Kafka Consumer Api,Spring Kafka,我正在使用卡夫卡主题中包含区号的数据。我必须只过滤某些区号的数据。有谁能建议这是解决这一问题的最佳方法 下面是我的侦听器代码。最佳做法是将数据解析为对象(当我将有效负载映射到测试对象时)并根据需要过滤的值过滤数据,还是kafka提供了我可以使用此过滤过程的任何其他库 卡夫卡侦听器方法 @Service public class Listener{ @KafkaListener(topics = "#{@topicName}") public void listen(St

我正在使用卡夫卡主题中包含区号的数据。我必须只过滤某些区号的数据。有谁能建议这是解决这一问题的最佳方法

下面是我的侦听器代码。最佳做法是将数据解析为对象(当我将有效负载映射到测试对象时)并根据需要过滤的值过滤数据,还是kafka提供了我可以使用此过滤过程的任何其他库

卡夫卡侦听器方法

@Service
public class Listener{

    @KafkaListener(topics = "#{@topicName}")
        public void listen(String payload) throws IOException {

            LOGGER.info("received payload from topic='{}'", payload);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            TEST test = objectMapper.readValue(payload,TEST.class);

        }
}
我的卡夫卡配置类:

@Configuration
public class Config {


    @Bean
    public Map<String, Object> consumerConfigs() {
        Map<String, Object> properties = new HashMap<>();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, applicationConfiguration.getKafkaBootStrap());
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, applicationConfiguration.getKafkaKeyDeserializer());
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, applicationConfiguration.getKafkaValueDeserializer());
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, applicationConfiguration.getKafkaGroupId());
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, applicationConfiguration.getKafkaAutoOffsetReset());
        return properties;
    }

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

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

        return factory;
    }
    @Bean
    public Listener receiver() {
        return new Listener();
    }

}
@配置
公共类配置{
@豆子
公共地图使用者配置(){
映射属性=新的HashMap();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,applicationConfiguration.getKafkaBootStrap());
properties.put(ConsumerConfig.KEY\u反序列化程序\u CLASS\u配置,applicationConfiguration.getKafkaKeyDeserializer());
properties.put(ConsumerConfig.VALUE_反序列化器_CLASS_CONFIG,applicationConfiguration.getKafkaValueDeserializer());
properties.put(ConsumerConfig.GROUP_ID_CONFIG,applicationConfiguration.getKafkaGroupId());
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,applicationConfiguration.getKafkaAutoOffsetReset());
归还财产;
}
@豆子
公共消费者工厂消费者工厂(){
返回新的DefaultKafkanConsumerFactory(consumerConfigs());
}
@豆子
公共KafkaListenerContainerFactory KafkaListenerContainerFactory(){
ConcurrentKafkalistener集装箱工厂=
新的ConcurrentKafkaListenerContainerFactory();
setConsumerFactory(consumerFactory());
返回工厂;
}
@豆子
公共侦听器接收器(){
返回新的侦听器();
}
}

你所做的一切都很好。
如果您的负载除了区号之外还有很多数据,并且您担心解析时间过长,那么您可以在对测试对象进行整个解析之前过滤消息,方法是将区号添加为头

卡夫卡的更高版本(0.11之后)提供了自定义()

如果您想自己实现它(或者如果您使用较旧版本的Kafka),您可以将头添加到消息负载中,比如消息的前4个字节,它们将表示区号,并且可以在解析过程之前快速提取。
新消息有效负载:

([header-4-bytes],[original-payload-n-bytes])
因此,根据头创建过滤器,如果发现这是您需要的区号,则根据消息的其余部分创建测试对象(剪切前4个字节以删除头)

卡夫卡不提供任何有助于您的过滤选项,尽管它能够在您的制作人中发送密钥消息,因此如果您的密钥是区号,卡夫卡保证所有具有相同区号的消息都会发送到同一分区,如果使用正确,可能会对您的性能有所帮助。

制作人还可以将消息发送到特定分区,因此,如果您知道您有固定的区号,您也可以使用分区号等于唯一区号计数来定义主题,并将每个区号发送到不同的分区,然后使用您的使用者仅访问带有您要查找的区号的分区,但是,在大多数情况下,这可能是过火了。

你所做的一切都很好。
如果您的负载除了区号之外还有很多数据,并且您担心解析时间过长,那么您可以在对测试对象进行整个解析之前过滤消息,方法是将区号添加为头

卡夫卡的更高版本(0.11之后)提供了自定义()

如果您想自己实现它(或者如果您使用较旧版本的Kafka),您可以将头添加到消息负载中,比如消息的前4个字节,它们将表示区号,并且可以在解析过程之前快速提取。
新消息有效负载:

([header-4-bytes],[original-payload-n-bytes])
因此,根据头创建过滤器,如果发现这是您需要的区号,则根据消息的其余部分创建测试对象(剪切前4个字节以删除头)

卡夫卡不提供任何有助于您的过滤选项,尽管它能够在您的制作人中发送密钥消息,因此如果您的密钥是区号,卡夫卡保证所有具有相同区号的消息都会发送到同一分区,如果使用正确,可能会对您的性能有所帮助。
制作人还可以将消息发送到特定分区,因此,如果您知道您有固定的区号,您也可以使用分区号等于唯一区号计数来定义主题,并将每个区号发送到不同的分区,然后使用您的使用者仅访问带有您要查找的区号的分区,但是,在大多数情况下可能是过度杀伤力。

请参阅

Spring for Apache Kafka项目还通过FilteringMessageListenerAdapter类提供了一些帮助,该类可以包装MessageListener。此类采用RecordFilterStrategy的实现,在该实现中,您实现filter方法来表示消息是重复的,应该丢弃。它还有一个名为ackDiscarded的附加属性,该属性指示适配器是否应确认丢弃的记录。默认情况下为false

当您使用
@KafkaListener
时,在容器工厂上设置
记录过滤器策略
(也可以选择ackDiscarded),以便将侦听器包装在适当的过滤适配器中

/**
*设置记录筛选策略。
*@param recordfilter使用该策略。
*/
公共无效设置RecordFilterStrategy(RecordFilterStrategy请参阅

Spring for Apache Kafka项目还通过FilteringMessageListenerAdapter类提供了一些帮助,该类可以包装MessageListener