1.消息发送方式
- 立即发送:不关注消息是否成功到达,大部分情况下,消息会成功送达至broker。但是还是会存在消息丢失的情况。
- 同步发送:调用send方法发送消息后,回去该方法的Future方法,根据对象的结果查看send方法调用是否成功
- 异步发送:先注册一个回调函数,通过调用send方法发送消息的时候把回调函数作为参数传入,这样当生产者接收到Kafka服务器的响应时会触发执行回调函数。
// 创建一个kafkaProdecer对象,传入上面创建的Properties对象
KafkaProducer<String,String> producer = new KafkaProducer<String, String>(myKafkaProps);
/**
* 使用ProdecerRecord<String,String>(String topic,String key,String value)构造函数创建消息
* 构造函数接受三个参数:
* topic--告诉kafkaProducer消息发送到哪个topic;
* key--告诉kafkaProducer,所发送消息的key值,需要和配置文件中的类型一直
* value--告诉kafkaProducer,消息所发送的value值,同上
*/
ProducerRecord<String,String> record = new ProducerRecord<String, String>("mySecondTopic","messageKey1","hello kafka");
//立即发送
producer.send(record);
//同步发送
Future<RecordMetadata> future = producer.send(record);
RecordMetadata recordMetadata = future.get();
//异步发送
producer.send(record,new Callback (){
public void onCompletion(RecordMetadata recordMetadata,Exception exception){
if (exception != null){
exception.printStackTrace();
}
else {
long offset = recordMetadata.offset();
int partition = recordMetadata.partition();
String topic = recordMetadata.topic();
System.out.println("the message offset : "+offset+" ,partition:"+partition+"。");
}
}
});
2.消息发送确认
消息的发送方式是站在消息生产者的角度宏观看其消息数据发送的情况的。而消息数据是存储在分区中的,而分区又有多个副本,所以一条消息在被发送到Broker之后何时算投递成功呢?Kafka提供了三种模式。
- acks=0 意味着生产者能够通过网络吧消息发送出去,那么就认为消息已成功写入Kafka 一定会丢失一些数据
- acks=1 意味着首领在疏导消息并把它写到分区数据问津是会返回确认或者错误响应,还是可能会丢数据
- acks=all 意味着首领在返回确认或错误响应之前,会等待所有同步副本都收到消息。如果和min.insync.replicas参数结合起来,,就可以决定在返回确认前至少有多个副本能够收到消息。但是效率较低。可以通过一部模式和更大的批次来加快速度,但这样做会降低吞吐量
3.消息重发
生产者提供了自动重试机制,当从Broker接收到的是临时可恢复的异常时,生产者会向Broker重发消息,但不能无限制重发,如果重发次数达到限制值,生产者将不再重试并返回错误。这里的限制值是由初始化生产者对象时的retries属性决定的,在默认情况下生产者会在重试后等待100ms,可通过retry.backoff.ms属性进行修改。建议在设置这两个参数前测试节点恢复所用时间,重试时间要比节点恢复时间要长,否则生产者会过早地放弃重试动作。
4.批次发送
生产者发送多个消息到同一个分区的时候,为了减少网络带来的系能开销,kafka会对消息进行批量发送
- batch.size :通过这个参数来设置批量提交的数据大小,默认是16k,当积压的消息达到这个值的时候就会统一发送(发往同一分区的消息)
- linger.ms :这个设置是为发送设置一定是延迟来收集更多的消息,默认大小是0ms(就是有消息就立即发送)