一、原生kafka
1、核心pom文件
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>0.9.0.1</version>
</dependency>
2、消息消费者
在消费者的类中,使用while死循环,一直占用线程监听testTopic这个topic是否有新消息。
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
import java.util.Set;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MyConsumer {
private static KafkaConsumer<String,String> consumer;
private static Properties properties;
static {
//设置kafka启动需要的参数
properties = new Properties();
//(kafka集群地址)broker地址
properties.put("bootstrap.servers","localhost:9092");
//key的反序列化方式
properties.put("key.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
//value的反序列化方式
properties.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
//消费组的id,属于哪个消费组
properties.put("group.id","cg1");
}
public static void getMessage(){
//是否自动提交
properties.put("enable.auto.commit",true);
consumer = new KafkaConsumer<>(properties);
Set<String> testTopic = Collections.singleton("testTopic");
log.info("topic set = {}",testTopic);
consumer.subscribe(new ArrayList<>(testTopic));
while (true){
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100).getSeconds());
for (ConsumerRecord<String, String> record : records) {
System.out.println(String.format("消费到的结果key:%s,value:%s,partition:%s",
record.key(),
record.value(),
record.partition()));
}
}
}
public static void main(String[] args) {
getMessage();
}
}
3、消息生产者
(1)同步发送,无返回值
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.springframework.stereotype.Component;
import org.apache.kafka.clients.producer.KafkaProducer;
@Component
public class MyProducer {
private static KafkaProducer<String,String> producer;
static {
//设置kafka启动需要的参数
Properties properties = new Properties();
//(kafka集群地址)broker地址
properties.put("bootstrap.servers","localhost:9092");
//key的序列化方式
properties.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
//value的序列化方式
properties.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
producer = new KafkaProducer<>(properties);
}
//发送消息不关注返回结果
public static void sendMessage(){
//ProducerRecord的三个参数,topic,发送的key,发送的value
ProducerRecord<String,String> record =
new ProducerRecord<>("testTopic","name","张三丰");
producer.send(record);
//关闭producer
producer.close();
}
public static void main(String[] args) {
sendMessage();
}
}
(2)同步发送,有返回值
private static class MyCallBack implements Callback {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
System.out.println("进入异步发送回调函数");
if(exception != null){
System.out.println("出现异常:"+exception.getMessage());
}
System.out.println(String.format("发送结果:topic:%s,存储的partition:%s,offset:%s",
metadata.topic(),
metadata.partition(),
metadata.offset()));
}
}
(3)异步发送,有返回值
在这里,kafka要求异步发送消息需要在send时指定一个callBack回调对象,我们新建一个类去实现CallBack接口,实现其中的onCompletio方法,这个方法有两个参数,一个是发送消息的元信息,一个是发送出现的异常,有异常就说明发送有问题,我们再新建一个sendMessageCallBack方法。
public static void sendMessageWithCareResult() throws ExecutionException, InterruptedException {
//ProducerRecord的三个参数,topic,发送的key,发送的value
ProducerRecord<String,String> record =
new ProducerRecord<>("testTopic","name","大不列颠亚瑟王");
//send的返回值是一个Future对象,可以通过get方法取出其中存储的发送消息的一些元信息RecordMetadata
Future<RecordMetadata> sendResult = producer.send(record);
RecordMetadata recordMetadata = sendResult.get();
//打印下发送消息的topic,partition,offset
System.out.println(String.format("发送结果:topic:%s,存储的partition:%s,offset:%s",
recordMetadata.topic(),
recordMetadata.partition(),
recordMetadata.offset()));
producer.close();
}
public static void sendMessage(){
//ProducerRecord的三个参数,topic,发送的key,发送的value
ProducerRecord<String,String> record =
new ProducerRecord<>("testTopic","name","张三丰");
producer.send(record,new MyCallBack());
//关闭producer
producer.close();
}
二、springboot整合kafka
1、核心pom文件
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
2、消息消费者(也就是监听器)
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class MyKafkaListener {
@KafkaListener(id = "tId", topics = "abcTopic")
public void listen(String input) {
System.out.println("kafkaInfo:"+input);
log.info("input value: {}" , input);
}
}
3、消息生产者
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/sd")
@Slf4j
public class SDController {
@Resource
private KafkaTemplate kafkaTemplate;
@GetMapping("/{aa}")
public Map<String,Object> send(@PathVariable(value = "aa") String s1){
ListenableFuture send = kafkaTemplate.send("abcTopic", s1);
HashMap<String, Object> result = new HashMap<>();
result.put("info",s1);
return result;
}
}