一、kafka简介
kafka是一个消息中间件,用于服务与服务之前的异步调用,追求吞吐量,适合产生大量数据的互联网服务的数据收集业务。
kafka中的专用名词
producer: 发布消息的对象称为主题生产者(Kafka topic producer)
topic: kafka将消息分类,每一类的消息称之为一个主题(Topic)
consumer: 订阅消息并处理发布的消息称之为主题消费者(consumer)
broker: 已发布的消息保存在一组服务器中,称之为kafka集群。集群中的每一个服务器都是一个broker(代理)
二、Kafka的基本使用
2-1 导入依赖
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
2-2 producer
//1、kafka连接配置
Properties properties = new Properties();
//kafka连接地址
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.200.130:9092");
//key和value的序列化
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
//2、创建kafka生产者对象
KafkaProducer<String, Object> product = new KafkaProducer<String, Object>(properties);
//3、 发送消息
ProducerRecord record = new ProducerRecord<String ,Object>("topic-first","key-001","hello kafka");
product.send(record);
//4、关闭消息通道 --- 一定要关闭消息通道,不然消息会发送不成功
product.close();
2-3 Consumer
//1、配置信息
Properties properties = new Properties();
//设置kafka连接地址
properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.200.130:9092");
//设置序列化器
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringDeserializer");
//设置消费者组
properties.put(ConsumerConfig.GROUP_ID_CONFIG,"group1");
//2、消费者对象
KafkaConsumer<String, Object> consumer = new KafkaConsumer<String, Object>(properties);
//3、订阅主题
ArrayList<String> list = new ArrayList<>();
list.add("topic-first");
consumer.subscribe(list);
//4、拉取消息
while (true) {
ConsumerRecords<String, Object> consumerRecords = consumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord<String, Object> consumerRecord : consumerRecords) {
System.out.println(consumerRecord.key());
System.out.println(consumerRecord.value());
}
}
2-4 生产者与消费者的关系
1、生产者生产消息,多个消费者同时订阅一个主题,当在同一个分组时(一对一)只有一个消费者可以拿到消息
2、生产者生产消息,多个消费者同时订阅一个主题,当在不同分组时(一对多)多个消费者可以拿到消息
三、Kafka的高可用设计
3-1 搭建kafka集群
搭建kafka集群可以提高kafka的高可用
3-2 备份机制(Replication)
kafka中消息的备份又叫做副本(Relica)
Kafka定义了俩类副本:
领导者副本(Leader Replica)
追随者副本(Follower Replica)
![](https://i-blog.csdnimg.cn/blog_migrate/6387657a674a8e6b8a41c9d670909ca8.png)
领导者副本又分成俩类
ISR 和 普通
ISR 需要同步复制保存的follower
![](https://i-blog.csdnimg.cn/blog_migrate/9b531debb3f7fbc7d440b2ae72062f93.png)
如果leader失败后,需要选出新的leader,选举的原则如下:
第一:优先从ISR中选定,这个列表中的follower的数据是跟leader同步的
第二:如果ISR列表中的follower都不行了,就只能从其他follower中获取
极端情况下,当所有副本都失效了,这时候有俩种方案
第一:等待ISR中的一个活过来,选为Leader,数据可靠,但活过来的时间不确定
第二:选择第一个活过来的Replication,不一定是ISR中的,选为leader,以最快数据恢复可用性,但数据不一定完整
四、kafka生产者详解
4-1 发送类型
同步发送
ProducerRecord record = new ProducerRecord<String ,Object>("topic-first","key-001","hello kafka");
product.send(record);
异步发送
ProducerRecord record = new ProducerRecord<String ,Object>("topic-first","key-001","hello kafka");
product.send(record);
product.send(record, new Callback() {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if(e != null) {
e.printStackTrace();
}
}
});
4-2 消息确认机制
ack配置,消息确认机制
![](https://i-blog.csdnimg.cn/blog_migrate/406e19e202a1d7fff49e8812a05ada09.png)
4-3 重试机制
![](https://i-blog.csdnimg.cn/blog_migrate/b48ca32f1ebea47e008a8edfa1ae4377.png)
4-4 消息压缩
![](https://i-blog.csdnimg.cn/blog_migrate/e3c721fa1645c6dabfcdd654c94fd566.png)
五、kafka消费者详解
5-1 消费者组
![](https://i-blog.csdnimg.cn/blog_migrate/34d65ca18ee08ed3aa04ec9abbcb559a.png)
5-2 消息有序性
![](https://i-blog.csdnimg.cn/blog_migrate/c37262f61739908062535e6abb6bd7ab.png)
5-3 提交和偏移值
![](https://i-blog.csdnimg.cn/blog_migrate/cd741b6b2cbf653808e72634596c661b.png)
六、springboot整合kafka
6-1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- kafkfa -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
6-2 添加配置
server:
port: 9991
spring:
application:
name: kafka-demo
kafka:
bootstrap-servers: 192.168.200.130:9092
producer:
retries: 10
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: ${spring.application.name}-test
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
6-3 书写消息生产者
@RestController
public class HelloController {
@Autowired
private KafkaTemplate<String,String> kafkaTemplate;
@GetMapping("/hello")
public String hello(){
kafkaTemplate.send("itcast-topic","黑马程序员");
return "ok";
}
}
6-4 书写消息消费者
@Component
public class HelloListener {
@KafkaListener(topics = "itcast-topic")
public void onMessage(String message){
if(!StringUtils.isEmpty(message)){
System.out.println(message);
}
}
}