Springboot集成Kafka完成消息回調,錯誤處理,消息攔截,批量處理

這篇文章主要是分享我做消息回調,錯誤處理,消息攔截,批量處理的一些代碼,希望大家給我指出不足之處。

消息回調

這個簡單,你只需要實現一個接口:ProducerListener

@Component
public class KafkaSendResultHandler implements ProducerListener {
    @Override
    public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata) {
        //成功時你的處理
    }

    @Override
    public void onError(ProducerRecord producerRecord, Exception exception) {
        //失敗時你的處理
    }
}

監聽時的錯誤處理

這個也很簡單,自己寫一個方法寫上你的業務處理,並且在監聽時將其配置就好,如果是批量處理時出錯,最好有一個單獨的出錯處理,否則可能會打很多無用日誌。

@Component
public class DefaultConsumerAwareListenerErrorHandler {
    @Bean
    public ConsumerAwareListenerErrorHandler consumerAwareErrorHandler() {
        return (message, e, consumer) -> {
            //錯誤處理
            return msg;
        };
    }
}

消息攔截

實現消息攔截首先實現RecordFilterStrategy接口,在接口中寫上自己的過濾規則,true爲捨棄,false爲保留,但是隻是這樣的話,對於代碼的拓展性是不太好的,因此我們可以通過接口回調來實現我們的自定義消息攔截規則:

@Component
public class DefaultRecordFilterStrategy implements RecordFilterStrategy {
	自己定義的接口,可通過實現該接口來實現自定義過濾規則來過濾規則。
	CustomFilter customFilter;
    @Override
    public final boolean filter(ConsumerRecord consumerRecord) {
        //先判斷冪等性,冪等性判斷消息是否爲重發
        /**
         * 冪等爲true,返回true
         */
        if(判斷冪等){
            return true;
        }
        //再判斷自定義規則
        return customFilter.rule(consumerRecord);
    }
}

批量處理

批量處理的話,需要實現關閉消息的自動應答,因此需要另建一個工廠:
KafkaConsumerConfig.java

@Bean("batchContainerFactory")
public ConcurrentKafkaListenerContainerFactory listenerContainer() {
    ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory();
    factory.setConsumerFactory(new DefaultKafkaConsumerFactory(batchConsumerConfigs()));
    factory.setAckDiscarded(true);
    factory.setRecordFilterStrategy(defaultRecordFilterStrategy);
    //設置併發量,小於或等於Topic的分區數
    factory.setConcurrency(maxPollRecords);
    //設置爲批量監聽
    factory.setBatchListener(true);
    return factory;
}
//批量消費配置
@Bean
public Map<String, Object> batchConsumerConfigs() {
    Map<String, Object> props = new HashMap<>();
    if(bootstrapServers.equals("aliyun")){
        bootstrapServers = CommonParam.aliyunServer;
    }else if(bootstrapServers.equals("dev")){
        bootstrapServers = CommonParam.DEVServer;
    }else{
        bootstrapServers = CommonParam.aliyunServer;
    }
    //自動提交的頻率
    props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, autoCommitInterval);
    //連接地址
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
    //是否開啓自動提交
    props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, autoCommit);
    //一次拉取消息數量
    props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, maxPollRecords);
    //連接超時時間
    props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
    //鍵反序列化方式
    props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class);
    //值反序列化方式
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    return props;
}

Listener.java

@KafkaListener(topics = "#{kafkaBatchTopicName}", groupId = "#{topicGroupId}", containerFactory = "batchContainerFactory", errorHandler = "batchConsumerAwareErrorHandler")
public void batchListen(List<String> list) {
    for (String s : list) {
        Message message = new GsonBuilder().create().fromJson(s, Message.class);
        
    }
}

希望大家可以指出我的不足之處,共同進步[手動加油]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章