Kafkaの複数の消費者が同じトピックを監視し、消費します

1.需要の紹介

トピックがあります:hw_dataには3つのパーティションと3つのコピーがあります
グループ:hw-data-group
は、このトピックのメッセージを2つ(またはそれ以上)のコンシューマーに配布して消費します(同じメッセージを消費することはできません)

1.グラフィック

ここに写真の説明を挿入

2.キー注釈@kafkaListener

ここに写真の説明を挿入

@Target({
    
     ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE })

@Retention(RetentionPolicy.RUNTIME)

@MessageMapping

@Documented

@Repeatable(KafkaListeners.class)

public @interface KafkaListener {
    
    

   /**
    * 消费者的id,当GroupId没有被配置的时候,默认id为GroupId
    */
   String id() default "";

   /**
    * 监听容器工厂,当监听时需要区分单数据还是多数据消费需要配置containerFactory      属性
    */
   String containerFactory() default "";

   /**
    * 需要监听的Topic,可监听多个,和 topicPattern 属性互斥
	*/
   String[] topics() default {
    
    };

   /**
    * 需要监听的Topic的正则表达。和 topics,topicPartitions属性互斥
    */
   String topicPattern() default "";


   /**
    * 可配置更加详细的监听信息,必须监听某个Topic中的指定分区,或者从offset为200的偏移量开始监听,可配置该参数, 和 topicPattern 属性互斥
    */
   TopicPartition[] topicPartitions() default {
    
    };

   /**
    *侦听器容器组 
    */
   String containerGroup() default "";

   /**
    * 监听异常处理器,配置BeanName
    */
   String errorHandler() default "";


   /**
    * 消费组ID 
    */
   String groupId() default "";

   /**
    * id是否为GroupId
    */
   boolean idIsGroup() default true;

   /**
    * 消费者Id前缀
    */
   String clientIdPrefix() default "";
   
   /**
    * 真实监听容器的BeanName,需要在 BeanName前加 "__"
    */
   String beanRef() default "__listener";
}

2、コードの実装

1)最初の消費者

package com.dataWarehouseOss.consumer;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.annotation.TopicPartition;
import org.springframework.stereotype.Component;

/**
 * @author :LiuShihao
 * @date :Created in 2020/9/16 4:15 下午
 * @desc :
 * containerGroup:侦听器容器组
 * topicPartitions:可配置更加详细的监听信息,必须监听某个Topic中的指定分区,或者从offset为200的偏移量开始监听,可配置该参数, 和 topicPattern 属性互斥
 */
@Slf4j
@Component
public class Consumer1 {
    
    
    @KafkaListener(containerGroup="first-group",topicPartitions = {
    
    @TopicPartition(topic = "first",partitions = {
    
    "0","1"})})
    public void m1(ConsumerRecord<String, String> record){
    
    
        log.info("分区0,1 :"+record.topic()+" : "+record.value());
    }
}

2)2番目の消費者

package com.dataWarehouseOss.consumer;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.annotation.TopicPartition;
import org.springframework.stereotype.Component;

/**
 * @author :LiuShihao
 * @date :Created in 2020/9/16 4:15 下午
 * @desc :
 * containerGroup:侦听器容器组
 * topicPartitions:可配置更加详细的监听信息,必须监听某个Topic中的指定分区,或者从offset为200的偏移量开始监听,可配置该参数, 和 topicPattern 属性互斥
 */
@Slf4j
@Component
public class Consumer2 {
    
    
    @KafkaListener(containerGroup="first-group",topicPartitions = {
    
    @TopicPartition(topic = "first",partitions = {
    
    "2"})})
    public void m1(ConsumerRecord<String, String> record){
    
    
        log.info("分区2 :"+record.topic()+" : "+record.value());
    }
}

3)プロデューサー

@Component
@Slf4j
public class SendKafkaToFirst {
    
    
    @Autowired
    KafkaTemplate kafkaTemplate;
    public static final String  TOPIC = "first";
    @Scheduled(cron = "0 */2 * * * ?")
    public void sendKafka(){
    
    
        log.info("---====定时任务执行了:向first发送10条数据====---");
        for (int i = 1; i <=10 ; i++) {
    
    
            kafkaTemplate.send(TOPIC,i+"");
            log.info("---==="+i+"===---");
        }
    }
}

3、テスト


最初のトピックの3つのパーティションと3つのコピーを作成します。最初のトピックに10個のデータを送信します。
ここに写真の説明を挿入
送信したデータを確認できますそして、繰り返し消費されていません

おすすめ

転載: blog.csdn.net/DreamsArchitects/article/details/108622640