初识 Kafka
Kafka是一个分布式流式处理平台。这到底是什么意思呢?
流平台具有三个关键功能:
1.消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是Kafka也被归类为消息队列的原因。
2.容错的持久方式存储记录消息流:Kafka会把消息持久化到磁盘,有效避免了消息丢失的风险·。
3.流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。
Kafka主要有两大应用场景:
1.消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
2.数据处理: 构建实时的流数据处理程序来转换或处理数据流。
关于Kafka几个非常重要的概念:
1.Kafka将记录流(流数据)存储在 topic 中。
2.每个记录由一个键、一个值、一个时间戳组成。
创建配置Kafka
通过Spring 官方提供的 Spring Initializr 创建或者直接使用 IDEA 创建皆可。
通过 application.yml 配置文件配置 Kafka 基本信息
server:
port:9090
spring:
kafka:
consumer:
bootstrap-servers:localhost:9092
# 配置消费者消息offset是否自动重置(消费者重连会能够接收最开始的消息)
auto-offset-reset:earliest
producer:
bootstrap-servers:localhost:9092
# 发送的对象信息变为json格式
value-serializer:org.springframework.kafka.support.serializer.JsonSerializer
kafka:
topic:
my-topic:my-topic
my-topic2:my-topic2
创建发送消息的生产者
我们使用Kafka提供的KafkaTemplate调用 send()方法出入要发往的topic和消息内容即可很方便的完成消息的发送:
kafkaTemplate.send(topic, o);
public void sendMessage(String topic, Object o) {
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(topic, o);
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onSuccess(SendResult<String, Object> sendResult) {
logger.info("生产者成功发送消息到" + topic + "-> " + sendResult.getProducerRecord().value().toString());
}
@Override
public void onFailure(Throwable throwable) {
logger.error("生产者发送消息:{} 失败,原因:{}", o.toString(), throwable.getMessage());
}
});
}
创建消费消息的消费者
通过在方法上使用@KafkaListener注解监听消息,当有消息的时候就会通过 poll 下来消费。
@Value("${kafka.topic.my-topic}")
private String myTopic;
@Value("${kafka.topic.my-topic2}")
private String myTopic2;
privatefinal Logger logger = LoggerFactory.getLogger(BookProducerService.class);
privatefinal ObjectMapper objectMapper = new ObjectMapper();
@KafkaListener(topics = {"${kafka.topic.my-topic}"}, groupId = "group1")
public void consumeMessage(ConsumerRecord<String, String> bookConsumerRecord) {
try {
Book book = objectMapper.readValue(bookConsumerRecord.value(), Book.class);
logger.info("消费者消费topic:{} partition:{}的消息 -> {}", bookConsumerRecord.topic(), bookConsumerRecord.partition(), book.toString());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@KafkaListener(topics = {"${kafka.topic.my-topic2}"}, groupId = "group2")
public void consumeMessage2(Book book) {
logger.info("消费者消费{}的消息 -> {}", myTopic2, book.toString());
}