Kafka的Java客户端-消费者设置自动提交和手动提交offset

1)提交的内容

消费者⽆论是⾃动提交还是⼿动提交,都需要把所属的消费组+消费的某个主题+消费的某个分区及消费的偏移量,这样的信息提交到集群的_consumer_offsets主题⾥⾯。


基础代码

package com.qf.kafka;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;

public class MySimpleConsumer {
   private final static String TOPIC_NAME = "my-replicated-topic";
   private final static String CONSUMER_GROUP_NAME = "testGroup";
   public static void main(String[] args) {
       Properties props = new Properties();
       props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,    
       "172.16.253.38:9092,172.16.253.38:9093,172.16.253.38:9094");
       // 消费分组名
       props.put(ConsumerConfig.GROUP_ID_CONFIG, CONSUMER_GROUP_NAME);
       props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, 
       StringDeserializer.class.getName());
       props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, 
       StringDeserializer.class.getName());
       //1.创建⼀个消费者的客户端
       KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>
       (props);
       //2. 消费者订阅主题列表
       consumer.subscribe(Arrays.asList(TOPIC_NAME));
       while (true) {
       //3.poll() API 是拉取消息的⻓轮询
        ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));
        for (ConsumerRecord<String, String> record : records) {
        //4.打印消息
        System.out.printf("收到消息:partition = %d,offset = %d, key = %s, value = %s%n", record.partition(), record.offset(), record.key(), record.value());      
        }    
     }  
  }
}

2)自动提交

消费者poll消息下来以后就会⾃动提交offset

// 是否⾃动提交offset,默认就是true
 props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");
// ⾃动提交offset的间隔时间
 props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");

注意:⾃动提交会丢消息。因为消费者在消费前提交offset,有可能提交完后还没消费时消费者挂了。

3)手动提交

需要把⾃动提交的配置改成false

// 是否⾃动提交offset,默认就是true
 props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");

分成两种:

1.⼿动同步提交
在消费完消息后调⽤同步提交的⽅法,当集群返回ack前⼀直阻塞,返回ack后表示提交成功,执⾏之后的逻辑,⼀般使⽤手动同步提交

while (true) {      
	/*       
	* poll() API 是拉取消息的⻓轮询       
	*/     
	 ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); 
	 for (ConsumerRecord<String, String> record : records) {      
	     System.out.printf("收到消息:partition = %d,offset = %d, key = %s, value = %s%n",  
	        record.partition(),record.offset(), record.key(), record.value());      
	  }      
	  //所有的消息已消费完      
	  if (records.count() > 0) {//有消息        
		  // ⼿动同步提交offset,当前线程会阻塞直到offset提交成功        
		  // ⼀般使⽤手动同步提交,因为提交之后⼀般也没有什么逻辑代码了        
		  consumer.commitSync();//=======阻塞=== 提交成功      
	  }  
}  

2.⼿动异步提交
在消息消费完后提交,不需要等到集群ack,直接执⾏之后的逻辑,可以设置⼀个回调⽅法,供集群调⽤

while (true) {      
	/*       
	* poll() API 是拉取消息的⻓轮询       
	*/     
	 ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); 
	 for (ConsumerRecord<String, String> record : records) {      
	     System.out.printf("收到消息:partition = %d,offset = %d, key = %s, value = %s%n",  
	        record.partition(),record.offset(), record.key(), record.value());      
	  }      
	  //所有的消息已消费完      
	  if (records.count() > 0) {//有消息        
		  // ⼿动异步提交offset,当前线程提交offset不会阻塞,可以继续处理后⾯的程序逻辑
		  consumer.commitAsync(new OffsetCommitCallback() {          
			   @Override         
			   public void onComplete(Map<TopicPartition, OffsetAndMetadata> offsets, Exception exception) { 
				   if (exception != null) {              
					   System.err.println("Commit failed for " + offsets);    
					   System.err.println("Commit failed exception: " 
					   +exception.getStackTrace());  
				   }
		       }        
		   });
	  }   
 } 
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值