Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。
Kafka 有如下特性:
kafka有四个核心API
windows 上 Kafka 启动
还有更多配置,可以去查看官方文档,这里就不在说明了。
下面,我们通过在Spring Boot应用中整合kafka,并实现一个简单的发送、接收消息的例子来对kafka有一个直观的感受和理解。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.dyh.kafkagroupId>
<artifactId>kafkaartifactId>
<version>1.0-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.10.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.kafkagroupId>
<artifactId>spring-kafkaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-autoconfigureartifactId>
dependency>
dependencies>
project>
server:
port: 1234
spring:
# devtools:
# restart:
# enabled: true
kafka:
# 以逗号分隔的地址列表,用于建立与Kafka集群的初始连接(kafka 默认的端口号为9092)
#bootstrap-servers: kmanager.ahsl.lab:9092
#bootstrap-servers: b-2.wangzx-kafka-test0.w3xikl.c2.kafka.cn-north-1.amazonaws.com.cn:9092,b-1.wangzx-kafka-test0.w3xikl.c2.kafka.cn-north-1.amazonaws.com.cn:9092
bootstrap-servers: localhost:9092
producer:
# properties:
# #事务ID
# enable.idempotence: true
# 发生错误后,消息重发的次数。
retries: 1
#当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
batch-size: 16384
# 设置生产者内存缓冲区的大小。
buffer-memory: 33554432
# 键的序列化方式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
# 值的序列化方式
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。
# acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。
# acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。
acks: 1
consumer:
properties:
#客户端超时时间
session.timeout.ms: 600000
# 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D
auto-commit-interval: 1S
# 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理:
# latest(默认值)在偏移量无效的情况下,消费者将从最新的记录开始读取数据(在消费者启动之后生成的记录)
# earliest :在偏移量无效的情况下,消费者将从起始位置读取分区的记录
auto-offset-reset: earliest
# 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
enable-auto-commit: false
# 键的反序列化方式
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# 值的反序列化方式
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
group-id: topic-dyh-group
listener:
missing-topics-fatal: false
# 在侦听器容器中运行的线程数。
concurrency: 10
ack-mode: manual
logging:
level:
org:
springframework:
kafka: ERROR # spring-kafka INFO 日志太多了,所以我们限制只打印 ERROR 级别
apache:
kafka: ERROR # kafka INFO 日志太多了,所以我们限制只打印 ERROR 级别
package com.dyh.kafka.producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.UUID;
/**
* @ClassName: Producer
* @author: 〆、dyh
* @since: 2022/12/21 15:23
*/
@Component
public class Producer {
@Autowired
private KafkaTemplate kafkaTemplate;
public void send(String msg) {
kafkaTemplate.send("topic-dyh", msg);
}
}
package com.dyh.kafka.consumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
/**
* @ClassName: Consumer
* @author: 〆、dyh
* @since: 2022/12/21 15:25
*/
@Component
public class Consumer {
@KafkaListener(id = "id",
topics = "topic-dyh",
groupId = "topic-dyh-group")
public void onMessage(ConsumerRecord<Long, String> record, Acknowledgment acknowledgment) {
if (Objects.nonNull(record.value())) {
System.out.println("线程编号:" + Thread.currentThread().getId() + ",消息内容:" + record.value());
try {
System.out.println("消费:" + record.value());
//手动提交
acknowledgment.acknowledge();
} catch (Exception e) {
e.printStackTrace();
acknowledgment.acknowledge();
} finally {
acknowledgment.acknowledge();
}
}
}
}
package com.dyh.kafka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @ClassName: Application
* @author: 〆、dyh
* @since: 2022/12/21 15:26
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.dyh.kafka;
import com.dyh.kafka.producer.Producer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @ClassName: Test
* @author: 〆、dyh
* @since: 2022/12/21 15:35
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestKafka {
@Autowired
private Producer producer;
@Test
public void TestSend() {
System.out.println("生产一头牛");
producer.send("一头牛");
}
}
控制台输出
生产一头牛
线程编号:21,消息内容:一头牛
消费:一头牛
简单的开发一个kafka的程序需要以下步骤:
当然项目我放在gitee上了,有兴趣的可以看看。https://gitee.com/DuanYuHong/kafka