1. 生产者发送消息
Properties properties = new Properties();
// 设置地址, 这里所有的参数都在producerConfig这个类里
properties.put("bootstrap.servers", "localhost:9092");
properties.put("acks", "-1"); // 设置ack模式
properties.put("retries", "1"); // 重试次数
properties.put("batch.size", "16384"); // 批次大小
properties.put("linger.ms", "1"); // 等待时间
properties.put("buffer.memory", "33554432"); // 缓冲区大小
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
// 不带回调函数的,第一个参数topic,第二个是message
kafkaProducer.send(new ProducerRecord<String, String>("test", "hello"));
kafkaProducer.close();
生产者发送消息的集中姿势
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
// 1. 不带回调函数的
kafkaProducer.send(new ProducerRecord<String, String>("test", "hello"));
// 2. 增加回调函数
kafkaProducer.send(new ProducerRecord<String, String>("test", "hello"),
new Callback() {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
System.out.println(metadata.offset() + "----" + metadata.partition());
}
});
// 3. 指定数据的分区
// 第一个参数topic,第二个指定第几个分区,第三个指定key,第四个message
kafkaProducer.send(new ProducerRecord<String, String>("test",0,"atguigu", "love"),
new Callback() {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
System.out.println(metadata.offset() + "----" + metadata.partition());
}
});
2. 消费者接受消息
Properties properties = new Properties();
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); // 连接的地址
properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000"); // 自动提交延迟
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true); // 开启自动提交
properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put(ConsumerConfig.GROUP_ID_CONFIG, "atguigu"); // 设置消费者组
// 设置消费者的offset earliest就是会获取最早的数据 latest 是从最新的数据开始获取
properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(Arrays.asList("test")); // 订阅消息
while (true){
// 获取数据
ConsumerRecords<String, String> datas = consumer.poll(100);
for (ConsumerRecord<String, String> data : datas) {
System.out.println(data.key());
}
}
当关闭自动提交之后,我们可以手动进行提交
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(Arrays.asList("test"));
// 同步提交
consumer.commitSync();
// 异步提交
consumer.commitAsync(new OffsetCommitCallback() {
@Override
public void onComplete(Map<TopicPartition, OffsetAndMetadata> offsets, Exception exception) {
System.out.println(offsets.keySet());
}
});
3. 自定义分区器
自定义分区器需要实现接口
public class Partitioner1 implements Partitioner {
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
// 返回分区编号
return 1;
}
@Override
public void close() {
// 关闭
}
@Override
public void configure(Map<String, ?> configs) {
// 配置
}
}
进行注册使用
// 需要在properties中进行全类名的注册
properties.put("partitioner.class", "com.data.spark.core.test.Partitioner1");
4. 自定义拦截器
public class MyTimeInterceptor implements ProducerInterceptor<String, String> {
Integer success = 0;
Integer error = 0;
// 发送前对消息做的处理
@Override
public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
// 获取数据
String value = record.value();
// 需要返回一个新的ProducerRecord对象
return new ProducerRecord<>(record.topic(), record.partition(), record.key()
,System.currentTimeMillis()+", "+record.value());
}
// 成功发送到kafka的broker,或者发送过程失败会调用
@Override
public void onAcknowledgement(RecordMetadata metadata, Exception exception) {
if(metadata != null){
success += 1;
}else {
error -= 1;
}
}
// 关闭过滤器,做清理工作
@Override
public void close() {
System.out.println("closing...");
System.out.println("success" + success);
System.out.println("error" + error);
}
// 配置信息
@Override
public void configure(Map<String, ?> configs) {
}
}
注册使用拦截器
// 在properties中进行全类名的注册,可以添加多个拦截器
ArrayList<String> interCeptors = new ArrayList<>();
interCeptors.add("com.data.spark.core.test.MyTimeInterceptor");
properties.put("interceptor.classes", interCeptors);
5. 自定义offset的存储
public class MyTest implements ConsumerRebalanceListener {
@Override
public void onPartitionsRevoked(Collection<TopicPartition> partitions) {
// 在Rebalance方法之前进行调用
}
@Override
public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
// 在Rebalance方法之后进行调用
}
}
在消费端使用
kafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
consumer.subscribe(Arrays.asList("test"), new MyTest()); // 将自定义offset的存储对象传入