在日常的开发工作中,kafka作为消息处理中间件,会经常在SpringBoot的应用中连接kafka,消费kakfa中的流式数据,那么怎么优雅的集成kafka,有什么使用的小技巧呢?
引入kafka依赖包
我们可以直接在pom.xml文件中直接加入依赖的包
org.springframework.kafka
spring-kafka
我们也可以在创建SpringBoot应用时,选择kafka的支持,有IDEA自动引入kafka依赖包
设置配置文件
由于kafka连接时需要,配置一些连接配置项目,所以需要在SpringBoot的配置文件中配置一下
本例采用的是 yml文件的方式,可以减少配置项目名字前缀的重复输入,但是要注意配置项前空格的个数,否则会读取不到配置项。
spring:
kafka:
consumer:
#kakfa broker服务的连接地址
bootstrap-servers: 192.168.159.141:9092
#设置消息的消费方式,从最早的消息开始消费
auto-offset-reset:earliest
#设置key的反序列化类
key-deserializer:org.apache.kafka.common.serialization.StringDeserializer
value-deserializer:org.apache.kafka.common.serialization.StringDeserializer
group-id: gruop1
#实时数据topic的前缀
topic-pattern: measurement.*
对于有多个kafka broker地址的情况,bootstrap-servers配置时 采用逗号分隔的方式
实现消费监听类
本例是打印topic,以及接受的数据内容
注意:接收的topic是通过配置类完成的。
@Component
public classKafkaConsumerLisenterimplementsMessageListener
{ @Override
public voidonMessage(ConsumerRecord
data) { String topic = data.topic();
String value = data.value();
System.out.println(topic +" "+ value);
}
}
建立配置类
1、主要在配置类定义时,加入@EnableKafka和@Configuration注解
2、通过@Value注解,引入配置文件在的配置项
3、加入@Bean,生成Bean
@Configuration
@EnableKafka
@AutoConfigureBefore
public classkafka {
@Value("${spring.kafka.consumer.bootstrap-servers}")
privateStringbootstrapServers;
@Value("${spring.kafka.consumer.auto-offset-reset}")
privateStringautoOffsetReset;
@Value("${spring.kafka.consumer.group-id}")
privateStringgroupId;
@Value("${spring.kafka.consumer.topic-pattern}")
privateStringtopicPattern;
@Resource
privateKafkaConsumerLisenterkafkaConsumerListener;
/**
* 工厂配置
*/
@Bean
publicKafkaListenerContainerFactory>kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory factory =newConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.getContainerProperties().setPollTimeout(1500);
returnfactory;
}
@Bean
publicConsumerFactoryconsumerFactory() {
return newDefaultKafkaConsumerFactory<>(consumerConfigs());
}
@Bean
publicKafkaMessageListenerContainerlistenerContainer(ConsumerFactory cf) {
// 设置topics
ContainerProperties containerProperties =newContainerProperties(Pattern.compile(topicPattern));
// 设置消费者监听器
containerProperties.setMessageListener(kafkaConsumerListener);
KafkaMessageListenerContainer container =newKafkaMessageListenerContainer<>(cf,containerProperties);
container.setBeanName("KafkaMessageListenerContainer");
returncontainer;
}
/**
* 消费者基本配置
*@return
*/
privateMapconsumerConfigs(){
Map propsMap =newHashMap<>();
propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapServers);
propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,autoOffsetReset);
propsMap.put(ConsumerConfig.GROUP_ID_CONFIG,groupId);
propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);
propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);
returnpropsMap;
}
}
运行效果
2019-04-07 16:15:36.321 INFO 13752 --- [ main]o.a.kafka.common.utils.AppInfoParser: Kafka version : 2.0.1
2019-04-07 16:15:36.321 INFO 13752 --- [ main]o.a.kafka.common.utils.AppInfoParser: Kafka commitId : fa14705e51bd2ce5
2019-04-07 16:15:36.323 INFO 13752 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService
2019-04-07 16:15:36.345 INFO 13752 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-07 16:15:36.348 INFO 13752 --- [ main] com.bonc.study.kafka.KafkaApplication : Started KafkaApplication in 1.646 seconds (JVM running for 2.344)
2019-04-07 16:15:36.476 INFO 13752 --- [erContainer-C-1] org.apache.kafka.clients.Metadata : Cluster ID: 9QsjfRM9SLGp9N4-F8PyAQ
2019-04-07 16:15:36.477 INFO 13752 --- [erContainer-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-1, groupId=gruop1] Discovered group coordinator 192.168.159.141:9092 (id: 2147483647 rack: null)
2019-04-07 16:15:36.484 INFO 13752 --- [erContainer-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-1, groupId=gruop1] Revoking previously assigned partitions []
2019-04-07 16:15:36.484 INFO 13752 --- [erContainer-C-1] o.s.k.l.KafkaMessageListenerContainer : partitions revoked: []
2019-04-07 16:15:36.484 INFO 13752 --- [erContainer-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-1, groupId=gruop1] (Re-)joining group
2019-04-07 16:15:41.705 INFO 13752 --- [erContainer-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-1, groupId=gruop1] Successfully joined group with generation 4
2019-04-07 16:15:41.706 INFO 13752 --- [erContainer-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-1, groupId=gruop1] Setting newly assigned partitions [measurement1-0, measurement2-1, measurement2-0]
2019-04-07 16:15:41.706 INFO 13752 --- [erContainer-C-1] o.s.k.l.KafkaMessageListenerContainer : partitions assigned: [measurement1-0,
measurement1 1,2,3,4,5,6
measurement1 12,3,4,5,6
使用技巧
当我们需要消费固定前缀的多个topic时,在配置文件中要使用 .* 的方式作为通配符。
例如:topic-pattern: measurement.*
The End.