這篇文章主要是分享我做消息回調,錯誤處理,消息攔截,批量處理的一些代碼,希望大家給我指出不足之處。
消息回調
這個簡單,你只需要實現一個接口: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);
}
}
希望大家可以指出我的不足之處,共同進步[手動加油]