版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Simon_09010817/article/details/83748974
Kafka的高阶消费者(high-level consumer)和低阶消费者(low-level consumer,底层用SimpleConsumer实现)是旧版本的consumer中的。
新版本的consumer中没有这两个概念。新版本把高阶消费者和低阶消费者整合到一起了,对应KafkaConsumer类的subscribe和assign方法。
创建消费者:
String kafkas = "192.168.1.100:9092,192.168.1.100:9093,192.168.1.100:9094";
Properties props = new Properties();
//kafka连接信息
props.put("bootstrap.servers",kafkas);
//消费者组id
props.put("group.id", "test_group");
//是否自动提交offset
props.put("enable.auto.commit", "true");
//在没有offset的情况下采取的拉取策略
props.put("auto.offset.reset", "none");
//自动提交时间间隔
props.put("auto.commit.interval.ms", "1000");
//key反序列化
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
//value反序列化
props.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
订阅主题:
一个消费者可以同时订阅多个主题,可以以集合的形式指定多个主题,也可以以正则表达式形式订阅特定模式主题。
三种订阅方式:
public void subscribe(Collection<String> topics) {
this.subscribe((Collection)topics, new NoOpConsumerRebalanceListener());
}
public void subscribe(Collection<String> topics, ConsumerRebalanceListener listener) {
this.acquire();
try {
if(topics.isEmpty()) {
this.unsubscribe();
} else {
log.debug("Subscribed to topic(s): {}", Utils.join(topics, ", "));
this.subscriptions.subscribe(topics, listener);
this.metadata.setTopics(this.subscriptions.groupSubscription());
}
} finally {
this.release();
}
}
public void subscribe(Pattern pattern, ConsumerRebalanceListener listener) {
this.acquire();
try {
log.debug("Subscribed to pattern: {}", pattern);
this.subscriptions.subscribe(pattern, listener);
this.metadata.needMetadataForAllTopics(true);
this.metadata.requestUpdate();
} finally {
this.release();
}
}
同时订阅主题时还可以注册一个回调监听器(ConsumerRebalanceListener接口),用于当消费者发生平衡时回调处理。
// 2、创建KafkaConsumer
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
// 3、订阅数据,给定监听器
consumer.subscribe(Collections.singleton(topic), new ConsumerRebalanceListener() {
//消费者平衡操作开始之前、消费者停止拉取消息之后被调用(可以提交偏移量以避免数据重复消费)
@Override public void onPartitionsRevoked(Collection<TopicPartition> collection) {
//提交偏移量
consumer.commitSync();
}
//消费者平衡操作之后、消费者开始拉取消息之前被调用(可以在该方法中保证各消费者回滚到正确的偏移量,重置各消费者偏移量)
@Override public void onPartitionsAssigned(Collection<TopicPartition> collection) {
long committedOffset = -1;
for(TopicPartition topicPartition : collection){
//获取该分区已消费的偏移量
committedOffset = consumer.committed(topicPartition).offset();
//重置偏移量到上一次提交的偏移量下一个位置开始消费
consumer.seek(topicPartition,committedOffset + 1);
}
}
});
订阅指定分区:
通过subscribe()方法订阅主题具有消费者自动均衡的功能。在多线程情况下,多个消费者进程根据分区分配策略自动分配消费者线程与分区的关系,当一个消费者组的消费者发生增减变化,分区分配会自动调整,以实现消费负载均衡及故障自动转移。指定分区assign()方法订阅主题不具有自动均衡的功能。
consumer.assign(Arrays.asList(new TopicPartition(topic, 0),new TopicPartition(topic, 1)));
偏移量管理:
Kafka提供两种查询偏移量的方法:
1.committed():返回OffsetAndMetadata对象,通过该对象获取指定分区已提交的偏移量。
TopicPartition topicPartition = new TopicPartition(topic, 0);
OffsetAndMetadata offsetAndMetadata = consumer.committed(topicPartition);
long offset = offsetAndMetadata.offset();
2.position():返回下一次拉取的位置
long position = consumer.position(topicPartition);
Kafka提供重置消费者偏移量的方法:
1.seek():将消费者起始位置重置到指定偏移量位置
//指定offset消费.
consumer.seek(topicPartition,103);
2.seekToBeginning():指定从消息起始位置开始消费,对应(auto.offset.reset=earlist)
//指定从最先消费
consumer.seekToBeginning(Collections.singleton(topicPartition));
3.seekToEnd():指定从最新消息对应的位置开始消费,有新消息才消费。对应(auto.offset.reset=latest)
//指定从最新消费(舍弃)
consumer.seekToEnd(Collections.singleton(topicPartition));
Kafka消费者消费位移两种策略:
1.自动提交。
try{
// 4、获取数据
while (true) {
//长轮询拉取消息
ConsumerRecords<String, String> records = consumer.poll(100);
for (ConsumerRecord<String, String> record : records) {
System.out.printf("topic = %s,partition = %d,offset = %d, key = %s, value = %s%n",
record.topic(), record.partition(),record.offset(), record.key(), record.value());
}
Thread.sleep(5000);
}
}catch (Exception e){
e.printStackTrace();
}
2.手动提交。
接下篇Kafka新版消费者API示例(二) https://blog.csdn.net/Simon_09010817/article/details/83750115