异步发送API
- 导入依赖
<dependencies>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>
- 编写代码
需要注意:
- KafkaProducer:需要创建一个生产者对象,用来发送数据
- ProducerConfig:获取所需的一系列配置参数
- ProducerRecord:每条数据都要封装成一个ProducerRecord对象
- 回调函数会在producer收到ack时调用,该方法有两个参数,分别是RecordMetadata和Exception,如果Exception为null,说明消息发送成功,如果Exception不为null,说明消息发送失败。
注意:消息发送失败会自动重试,不需要我们在回调函数中手动重试。
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Properties;
public class CustomProducer {
public static void main(String[] args) {
//1.创建kafka生产者的配置对象
Properties properties = new Properties();
//2.给kafka配置对象添加配置信息
properties.put("bootstrap.servers","hadoop102:9092");
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop102:9092");
//批次处理
properties.put("batch.size",16384);
//等待时间(默认0,现在kafka作为事件流平台,这个值就不用设置了,来一条刷写一条)
properties.put("linger.ms",1);
//RecordAccumulator(线程共享变量)缓冲区大小,默认32M
properties.put("buffer.memory",33554432);
//key,value的序列化(必须要进行的)
properties.put("key.zerializer","org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 设置ack
properties.put("acks", "all");
// 重试次数
properties.put("retries", 3);
//3.创建kafka的生产者对象
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
//4.调用send,发送信息
for (int i = 0; i < 10 ; i++) {
//添加回调(回调函数可以方便看到消息发送的主题,分区和偏移量)
kafkaProducer.send(new ProducerRecord<>("producer", "kafka" + i), new Callback() {
//该方法在收到ack时异步调用
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if(e == null){
//如果没有异常,输出信息到控制台
System.out.println("success->"+ recordMetadata.offset());
}else{
//出现异常打印
e.printStackTrace();
}
}
});
}
//5.关闭资源,(关闭资源的时候会自动将数据刷写到消费者)
kafkaProducer.close();
}
}
同步发送API
同步发送的意思是,一条消息发送之后,会阻塞当前线程,直至返回ack。
由于send方法返回的是一个Future对象,根据Futrue对象的特点,我们也可以实现同步发送的效果,只需在调用Future对象的get方发即可
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class CustomProducer {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 1. 创建kafka生产者的配置对象
Properties properties = new Properties();
// 2. 给kafka配置对象添加配置信息
properties.put("bootstrap.servers","hadoop102:9092");
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
// key,value序列化(必须要进行的)
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 设置ack
properties.put("acks", "all");
// 重试次数
properties.put("retries", 3);
// 批次大小 默认16K
properties.put("batch.size", 16384);
// 等待时间
properties.put("linger.ms", 1);
// RecordAccumulator缓冲区大小 默认32M
properties.put("buffer.memory", 33554432);
// 3. 创建kafka生产者对象
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
// 4. 调用send方法,发送消息
for (int i = 0; i < 10; i++) {
//不带回调函数.
// 异步发送 默认
//kafkaProducer.send(new ProducerRecord<>("first","kafka" + i));
// 同步发送,java中的方法处理同步
kafkaProducer.send(new ProducerRecord<>("first","kafka" + i)).get();
}
// 5. 关闭资源
kafkaProducer.close();
}
}