异步发送流程
在整个流程中最关键的是两个线程main
线程与sender
线程与一个公共变量RecordAccumulator
。
main
线程向RecordAccumulator
发送数据,sender
线程从RecordAccumulator
读取数据。
在main
线程中,消息由Producer
发出,经过过滤器Interceptors
,序列化器Serializer
,分区器Partitioner
后分发给RecordAccumulator
。
相关参数:
batch.size
:只有数据积累到 batch.size
之后,Sender
才会发送数据。
linger.ms
:如果数据迟迟未达到 batch.size
,Sender
等待 linger.time
之后就会发送数据。
不带回调API
package com.company;
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException{
// 创建Kafka生产者配置对象
Properties props = new Properties();
// 连接指定的kafka集群
props.put("bootstrap.servers", "ch2:9092");
// 设置ack应答级别
props.put("acks", "all");
// 重试次数
props.put("retries", 1);
// 批次大小
props.put("batch.size", 16384);
// 等待时间
props.put("linger.ms", 1);
// RecordAccumulator 缓冲区大小
props.put("buffer.memory", 33554432);
// key的序列化
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// value的序列化
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 创建生产者对象
Producer<String, String> producer = new KafkaProducer<>(props);
for (int i = 0; i < 10; i++) {
// 发送数据
producer.send(new ProducerRecord<>("first", "a--"+i));
System.out.println(i);
}
// 释放资源
producer.close();
}
}
带回调API
package com.company;
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException{
// 创建Kafka生产者配置对象
Properties props = new Properties();
// 连接指定的kafka集群
props.put("bootstrap.servers", "ch2:9092");
// 设置ack应答级别
props.put("acks", "all");
// 重试次数
props.put("retries", 1);
// 批次大小
props.put("batch.size", 16384);
// 等待时间
props.put("linger.ms", 1);
// RecordAccumulator 缓冲区大小
props.put("buffer.memory", 33554432);
// key的序列化
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// value的序列化
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 创建生产者对象
Producer<String, String> producer = new KafkaProducer<>(props);
for (int i = 0; i < 10; i++) {
producer.send(new ProducerRecord<String, String>("first","a--"+i),
new Callback() {
// 回调函数,该方法会在 Producer 收到 ack 时调用,为异步调用
@Override
// 第一个参数为回调的返回值,第二个参数为报错的返回值
public void onCompletion(RecordMetadata metadata,Exception exception) {
if (exception == null) {
// 如果没有返回错误,那么输出回调的offset
System.out.println("success->" + metadata.offset());
} else {
// 如果返回错误,输出错误
exception.printStackTrace();
}
}
}
);
}
// 释放资源
producer.close();
}
}
同步发送
package com.company;
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException{
// 创建Kafka生产者配置对象
Properties props = new Properties();
// 连接指定的kafka集群
props.put("bootstrap.servers", "ch2:9092");
// 设置ack应答级别
props.put("acks", "all");
// 重试次数
props.put("retries", 1);
// 批次大小
props.put("batch.size", 16384);
// 等待时间
props.put("linger.ms", 1);
// RecordAccumulator 缓冲区大小
props.put("buffer.memory", 33554432);
// key的序列化
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// value的序列化
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 创建生产者对象
Producer<String, String> producer = new KafkaProducer<>(props);
for (int i = 0; i < 10; i++) {
// 加get方法,同步获得ack。同步发送的意思就是,一条消息发送之后,会阻塞当前线程,直至返回 ack。
producer.send(new ProducerRecord<String, String>("first","a--"+i)).get();
}
// 释放资源
producer.close();
}
}