文章目录
导入依赖
<!--自动注入KafkaTemplate使用-->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<!--自己配置信息并生成对象使用-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
配置服务和客户端信息
spring:
kafka:
bootstrap-servers: ip:9092
producer:
# 重试次数
retries: 0
# 生产者每个批次最多放多少条记录
batch-size: 16384
# 生产者一端总的可用发送缓冲区大小
buffer-memory: 33554432
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# 提交延时
properties:
linger.ms: 1
# 消费者的配置信息
consumer:
key-deserializer: org.apache.kafka.common.serialization.StringSerializer
value-deserializer: org.apache.kafka.common.serialization.StringSerializer
# 消费者组的名称
group-id: groupname
# 如果在kafka中找不到当前消费者的偏移量,则直接将偏移量重置为最早
auto-offset-reset: earliest
# 消费者的偏移量是自动提交还是手动提交
enable-auto-commit: true
生产者代码
@RestController
public class KafkaProducer {
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
// 发送消息
@GetMapping("/kafka/normal/{message}")
public void sendMessage1(@PathVariable("message") String normalMessage) {
kafkaTemplate.send("topic1", normalMessage);
}
}
消费者代码
@Component
public class KafkaConsumer {
// 消费监听
@KafkaListener(topics = {"topic1"})
public void onMessage1(ConsumerRecord<?, ?> record){
// 消费的哪个topic、partition的消息,打印出消息内容
System.out.println("简单消费:"+record.topic()+"-"+record.partition()+"-"+record.value());
}
}
带回调的生产者
@GetMapping("/kafka/callbackOne/{message}")
public void sendMessage2(@PathVariable("message") String callbackMessage) {
kafkaTemplate.send("topic1", callbackMessage).addCallback(success -> {
// 消息发送到的topic
String topic = success.getRecordMetadata().topic();
// 消息发送到的分区
int partition = success.getRecordMetadata().partition();
// 消息在分区内的offset
long offset = success.getRecordMetadata().offset();
System.out.println("发送消息成功:" + topic + "-" + partition + "-" + offset);
}, failure -> {
System.out.println("发送消息失败:" + failure.getMessage());
});
}
@GetMapping("/kafka/callbackTwo/{message}")
public void sendMessage3(@PathVariable("message") String callbackMessage) {
kafkaTemplate.send("topic1", callbackMessage).addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onFailure(Throwable ex) {
System.out.println("发送消息失败:"+ex.getMessage());
}
@Override
public void onSuccess(SendResult<String, Object> result) {
System.out.println("发送消息成功:" + result.getRecordMetadata().topic() + "-"
+ result.getRecordMetadata().partition() + "-" + result.getRecordMetadata().offset());
}
});
}
自己生成对象并配置信息
public static void main(String[] args) {
// 创建kafka生产者的配置信息
Properties prop = new Properties();
// 指定kafka集群
prop.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.0.166:9092");
// ACK应答级别
prop.put("acks","all");
// 重试次数
prop.put("retries","1");
// 批次大小
prop.put("batch.size",16384);
// 等待时间,如果指定时间内没有达到批次大小,则在指定时间后也会提交
prop.put("linger.ms",1);
// 缓冲区大小
prop.put("buffer.memory",33554432);
// key、value的序列化类
prop.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
prop.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
// 创建生产者对象
KafkaProducer<String, String> producer = new KafkaProducer<>(prop);
// 发送数据
producer.send(new ProducerRecord<>("test","测试数据"));
// 关闭资源
producer.close();
}
带回调函数的
public static void main(String[] args) {
// 创建kafka生产者的配置信息
Properties prop = new Properties();
// 指定kafka集群
prop.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.0.166:9092");
// ACK应答级别
prop.put("acks", "all");
// 重试次数
prop.put("retries", "1");
// 批次大小
prop.put("batch.size", 16384);
// 等待时间,如果指定时间内没有达到批次大小,则在指定时间后也会提交
prop.put("linger.ms", 1);
// 缓冲区大小
prop.put("buffer.memory", 33554432);
// key、value的序列化类
prop.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
prop.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// 创建生产者对象
KafkaProducer<String, String> producer = new KafkaProducer<>(prop);
// 发送数据
producer.send(new ProducerRecord<>("test", "测试数据2"), (metadata, exception) -> {
if (exception == null) {
// 获取生产的数据分配的分区和所在索引
System.out.println((metadata.partition() + "---" + metadata.offset()));
} else {
exception.printStackTrace();
}
});
// 关闭资源
producer.close();
}
自创建对象的消费者
// 创建kafka生产者的配置信息
Properties prop = new Properties();
// 指定kafka集群
prop.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.0.166:9092");
// 开启自动提交
prop.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
// 自动提交1秒
prop.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
prop.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
prop.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
prop.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
// 消费者组
prop.put(ConsumerConfig.GROUP_ID_CONFIG, "bigdata3");
// 设置如果此消费者组之前没有初始化过,则从头消费
prop.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");
KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(prop);
// 订阅主题
consumer.subscribe(Arrays.asList("test", "second"));
// 获取数据,如果拉取不到数据,可把超长时间取大点
ConsumerRecords<String, String> records = consumer.poll(500);
for (ConsumerRecord<String, String> record : records) {
System.out.println(record.key() + "===" +record.value());
}
consumer.close();
参考:https://blog.csdn.net/yuanlong122716/article/details/105160545/