生产者同步发送:
如果生产者发送消息没有收到ack,生产者会阻塞,阻塞时间为3s,如果还没有收到消息,则会进行重试,会进行3次重试
ack三个配置:
- acks = 0:表示Producer不需要等待任何broker确认收到消息的回复,就可以继续发送下一条消息,性能高。最容易丢消息
- acks = 1:至少要等待leader已经成功的将数据写入本地log.但是不需要等待素有的follower是否成功写入,就可以继续发送下一条消息这种情况下,如果follower没有成功备份数据,而此时leader又挂掉,则消息会丢失
- acks = all或者-1:需要等待 min.insync.replicas(默认为1,推荐配置大于2,如果配置为2,此时就需要leader和一个follower同步完后,才会返回ack)这个参数配置的副本个数都成功写入日志,这种策略会保证只要有一个备份存活就不会丢失数据,这是最强的数据保证
缓冲区配置说明:
//设置发送消息的本地缓冲区,如果设置了该缓冲区,消息会先发送到本地缓冲区,可以提高消息发送性能,默认值为33554432,即32MB
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);
/**
* kafka本地线程会从缓冲区取数据,批量发送到broker
* 设置批量发送消息的大小,默认值是16384,即16kb,就是说一个batch慢了16kb就发送出去
*/
props.put(ProducerConfig.BATCH_SIZE_CONFIG,16384);
/**
* 默认值是0,意思就是说消息必须立即被发送,但这样会影响性能
* 一般设置10毫秒左右,就是说这个消息发送完后会进入本地的一个batch,如果10毫秒内,这个batch满了16kb就会随batch一起发送出去
* 如果10毫秒,batch没满,那么也必须将消息发送出去,不能让消息的发送延迟时间太长
*/
props.put(ProducerConfig.LINGER_MS_CONFIG,10);
生产者异步发送:
异步发送,生产者发送完消息后就可以执行之后的业务,broker在收到消息后异步调用生产者提供的callback()方法
//异步回调方式发送消息
producer.send(producerRecord, new Callback() {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if(e != null){
System.out.println("发送消息失败:"+e.getStackTrace());
}
if(recordMetadata !=null){
System.out.println("同步方式发送消息结果:"+"topic-"+recordMetadata.topic()+"|partition-"+recordMetadata.partition()
+"|offset-"+recordMetadata.offset());
}
countDownLatch.countDown();
}
});