一、kafka概述
1.1 官方资料
官网地址: https://kafka.apache.org/
中文地址: https://kafka1x.apachecn.org/
1.2 kafka概述
Apache Kafka 是一个开源分布式事件流平台,被数千家公司用于高性能数据管道、流分析、数据集成和任务关键型应用程序。
- Apache Kafka是一个分布式流平台
- 可以容错,持久的方式保存记录
- 发布-订阅模式
kafka是由服务器 和客户端 组成的分布式系统,这些服务器和客户端通过高性能TCP网络协议进行通信,它可以部署在内部以及云环境中的裸机硬件、虚拟机或者容器上.
Apache Kafka是一个开源消息系统,由Scala写成。
是由Apache软件基金会开发的一个开源消息系统项目,该项目的目标是为处理实时数据提供一个统一、高质量、低等待的平台。
Kafka是一个分布式消息队列 :生产者、消费者的功能。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。
Kafka对消息保存时根据Topic「理解成一个队列即可」进行归类,发送消息者称为Producer ,消息接受者称为Consumer ,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker 。无论是kafka集群,还是producer和consumer都依赖zookeeper集群保存一些meta信息,来保证系统可用性.
1.3 kafka核心组件
Producer
:消息生产者,产生的消息将会被发送到某个Topic.Consumer
: 消息消费者,消费的消息内容来自某个TopicTopic
:消息根据topic进行归类,topic其本质是一个目录,即将同一主题消息归类到同一个目录Broker
:每一个kafka实例(或者说每台kafka服务器节点)就是一个broker,一个broker可以有多个topic.- Zookeeper:zookeeper集群不属于kafka内的组件,但kafka依赖zookeeper集群保存meta信息,所以在此做声明其重要性。
「注意事项: kafka之前版本依赖于zookeeper, 但是现在的新版本不再依赖于zk」
- Producer,消息生产者, 就是向kafka broker发消息的客户端;
- Consumer,消费的消费者, 向kafka broker获取取消息的客户端;
- Topic,表示主题;
- Broker,一台kafka服务器就是一个
broker
. 一个集群由多个borker组成. 一个broker可以容纳多个topic
;
这里需要注意的是:
- kafka生产者采用【push】模式将消息发送给kafka broker;
- kafka消费者采用【pull】模式订阅并消费消息
简单一下的原理图:
1.4 小节
- kafka基本组成部分及相关名词
- 知道你自己正在看的是kafka上手文章
二、kafka安装、配置
本次文章依然采用centos + docker
方式进行安装部署kafka.采用的是kafka 3.8.0版本
.
2.1 安装zookeeper
为了学习的完整性,依然采用zk + kafka的相对完整的方式安装、配置kafka环境.【注意事项】: 必须安装和配置好docker的相关环境,这里不再赘述,之后单独出一篇【一文上手docker】的文章吧
bash
docker pull zookeeper
docker run -itd --name=zk -p 2181:2181 zookeeper
安装kafka
bash
docker run --name my-kafka -itd -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=zk的ip或者域名:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka所在机器的ip:9092 -e KAFKA_HEAP_OPTS="-Xmx256M -Xms256M" -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 wurstmeister/kafka
安装参数说明:
- KAFKA_BROKER_ID=0, kafka集群的唯一表示符,服务器之间的交换均使用该ID
- KAFKA_ZOOKEEPER_CONNECT, kafka连接zookeeper的地址
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT, 配置端口信息
- KAFKA_LISTENERS=PLAINTEXT, 监听端口和ip
注意事项:
- 如果是云服务器,则必须开放远程访问端口号
- 如果采用提虚拟机,则必须关闭防火墙
- 验证服务是否可以正常访问,可以使用window下的
telnet ip地址 端口号
进行验证
安装完,启动服务结果如下所示:
2.2 基本使用命令
对于这些命令,旨在体会一下kafka
的工作姿势.
进入容器内部:
bash
docker exec -it my-kafka /bin/bas
- 其中
my-kafka
,这里表示容器名称,这里也可以使用容器id,但是不管使用啥都要替换为你自己的哦.
进入到命令目录: /opt/kafka/bin
bash
cd op/kafka/bin
2.2.1 kafka-topic.sh
使用--help
可以查看具体命令的帮助信息、参数等.
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-topics.sh --help
This tool helps to create, delete, describe, or change a topic.
# .... 其它省略了,太多了
通过帮助手册的说明, 这个命令就是操作topic
的,可以对主题进行创建、删除、修改等操作. 其中比较常用的操作如下所示:
--list
, 查看当前可用的topic
信息
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-topics.sh --list
Exception in thread "main" java.lang.IllegalArgumentException: Only one of --bootstrap-server or --zookeeper must be specified
at kafka.admin.TopicCommand$TopicCommandOptions.checkArgs(TopicCommand.scala:743)
at kafka.admin.TopicCommand$.main(TopicCommand.scala:53)
at kafka.admin.TopicCommand.main(TopicCommand.scala)
root@acca0c42f22f:/opt/kafka/bin#
直接执行命令,可能发现,完了,报错了... 遇到报错不必慌张,读一下错误信息即可,信息里说了在使用--list的时候,必须指定--bootstrap-server或者--zookeeper当中的一个
.在帮助手册当中可以找到关于这两个操作的说明:
bash
--bootstrap-server <String: server to REQUIRED: The Kafka server to connect
connect to> to. In case of providing this, a
direct Zookeeper connection won't be
required.
------------------------------------------------------------------------------
--zookeeper <String: hosts> DEPRECATED, The connection string for
the zookeeper connection in the form
host:port. Multiple hosts can be
given to allow fail-over.
通过以上的文字可以发现事情的真像了,我们指定一下--bootstrap-server
即可.
bash
./kafka-topics.sh --list --bootstrap-server localhost:9092
由于新创建的容器,所以这里并没有任何的主题信息.
--create
创建主题
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-topics.sh --create --topic rj-topic --bootstrap-server localhost:9092
Created topic rj-topic.
参数说明:
--create
, 表示创建一个新的topic--topic
, The topic to create, alter, describe or deleterj-topic
, 表示【主题的名称】--bootstrap-server
, 表示kafka
服务器的地址, 【必选参数
】
再次查看一下主题信息,这里使用到了--describe
,表示显示分区信息.
bash
oot@acca0c42f22f:/opt/kafka/bin# ./kafka-topics.sh --describe --topic rj-topic --bootstrap-server localhost:9092
Topic: rj-topic TopicId: Ji3wAwHfQlGl8U4NNqP-Ag PartitionCount: 1 ReplicationFactor: 1 Configs: segment.bytes=1073741824
Topic: rj-topic Partition: 0 Leader: 0 Replicas: 0 Isr: 0
root@acca0c42f22f:/opt/kafka/bin#
相关信息释义:
- Topic: rj-topic:
- 表示这个主题的名称是 "rj-topic"。
- TopicId: LzWxpHWQSe6vNBKN-XHTKQ:
- 主题的唯一标识符,通常由 Kafka 内部生成,用于唯一标识这个特定的主题。
- PartitionCount: 1:
- 表示这个主题有 1 个分区。分区是为了实现可扩展性和并行处理,将主题的数据分布在不同的分区中。
- ReplicationFactor: 1:
- 主题的副本因子为 1。副本是为了提高数据的可靠性和可用性,当一个副本不可用时,其他副本可以继续提供服务。
- Configs: segment.bytes=1073741824:
- 主题的配置信息,这里表示该主题的日志段大小为 1073741824 字节(1GB)。日志段是 Kafka 用于存储消息的文件,当达到一定大小或时间时,会创建新的日志段。
---------------------------------------------------分区信息部分------------------------------------------------------------------------
- Topic: rj-topic
- 表示主题名称
- Partition: 0
- 表示这是主题 "rj-topic" 的第 0 个分区。
- Leader: 1
- 该分区的领导者副本所在的 broker ID 为 1。领导者副本负责处理分区的读写请求,并协调其他副本的同步
- Replicas: 1
- 该分区的副本列表中只有一个副本,其 broker ID 为 1。副本用于数据备份和容错
- Isr: 1
- "In-Sync Replicas"(同步副本)的列表中只有一个副本,其 broker ID 为 1。同步副本是指与领导者副本保持同步的副本集合,用于保证数据的一致性。
- Elr(Earliest Log Replicated)
- 表示最早日志已复制状态。通常它可能用于指示某个分区中最早的日志条目是否已经被成功复制到足够数量的副本上,以满足数据持久性和可靠性的要求。具体的含义可能因 Kafka 的版本和配置而有所不同。
- LastKnownElr
- 指最后已知的最早日志已复制状态。它可能记录了上一次检查或记录时的Elr状态,以便在需要时进行比较或跟踪状态的变化。
输出的信息当中,涉及到了分区、副本等信息现在有个印象即可,详细信息待到【kafka集群】的时候再细聊.
2.2.2 kafka-console-producer.sh
Kafka 客户端通过网络与 Kafka 代理通信以写入(或读取)事件。收到事件后,代理将以持久且容错的方式存储事件,只要您需要,甚至可以永远存储。
运行控制台创建者客户端,将一些事件写入您的主题中。默认情况下,您输入的每一行都会导致将单独的事件写入主题。
查看一下kafka-console-producer.sh 帮助信息:
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-console-producer.sh --help
This tool helps to read data from standard input and publish it to Kafka.
Option Description
简单来说,就是向指定的主题发送消息.具体操作如下所示:
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-console-producer.sh --bootstrap-server localhost:9092 --topic rj-topic
>hello,kafka
>
此时,可以持续的发送消息,其中--topic rj-topic
,表示指定主题,该主题是我们在上边新创建的一个主题.现在将消息发送到指定主题了,我们可通过kafka-console-consumer.sh
来获取消息.
2.2.3 kafka-console-consumer.sh
bash
a396c47c6a8a:/opt/kafka/bin$ ./kafka-console-consumer.sh --help
This tool helps to read data from Kafka topics and outputs it to standard output
从kafka指定的主题当中,读取消息.其中通过查看帮助手册,比较重要的一个参数是--from-beginning
,释义如下所示:
bash
--from-beginning If the consumer does not already have
an established offset to consume
from, start with the earliest
message present in the log rather
than the latest message.
解释如下所示:
- 如果消费者在启动时没有已确定的偏移量(比如这是一个新的消费者组,或者之前的偏移量信息丢失),并且设置了--from-beginning参数:
- 消费者将从主题(topic)的最早消息位置开始消费。也就是说,它会从主题的起始位置开始读取消息,依次处理所有存储在日志中的历史消息,直到最新的消息。
- 如果没有设置这个参数:
- 默认情况下,消费者将从主题的最新消息位置(即日志的末尾)开始消费。这样可以确保消费者只处理新产生的消息,而不会重新处理历史消息。
生产数据, 会永久的存储在topic中, 除非按规则删除掉. 可以按时间删除, 也可以按存储容量大小进行相应的删除规则配置.
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic rj-topic --from-beginning
hello,kafka
- hello, kafka表示从队列当中获取的数据,此时已经被消费了.
- 从kafka-console-consumer.sh接收队列的消息, 在kafka-console-producer.sh 端发送消息
2.3 小节
- 通过命令行,体会一下消息的发送、接收
- 主题的相关概念
- 测试的时候,开启两个客户端,一个是生产者,另外一个是消费者
- 对于分区、副本等概念放到后续文章再说聊
- 实践出真知
三、spring boot整合kafka
Apache Kafka 的 Spring(spring-kafka)项目将核心的 Spring 概念应用于基于 Kafka 的消息传递解决方案的开发。它提供了一个 "模板" 作为发送消息的高级抽象。它还通过带有@KafkaListener注解的消息驱动的普通 Java 对象(POJO)以及一个 "监听器容器" 提供支持。这些库促进了依赖注入和声明式的使用。在所有这些情况下,你会看到与 Spring 框架中的 JMS 支持以及 Spring AMQP 中的 RabbitMQ 支持的相似之处。
Spring for Apache Kafka(spring-kafka)项目提供了以下功能:
- 高级抽象的消息发送模板KafkaTempalte
- 提供了一种高级抽象的方式来发送消息,使得开发者可以更方便地将消息发送到 Kafka 主题中,而无需直接处理底层的 Kafka 客户端 API 的复杂性。
- 支持消息驱动的 POJO 和监听器容器
- 通过@KafkaListener注解,支持消息驱动的普通 Java 对象(POJO)。这意味着可以使用熟悉的 Java 对象来处理来自 Kafka 的消息,而无需编写大量的特定于 Kafka 的代码。
- 提供了 "监听器容器",用于管理和协调多个消息监听器,确保消息能够被正确地接收和处理。
- 促进依赖注入和声明式编程
- 像 Spring 框架的其他部分一样,促进了依赖注入的使用,使得组件之间的耦合度降低,提高了代码的可测试性和可维护性。
- 支持声明式编程,开发者可以通过配置的方式来定义消息的处理逻辑,而不是通过大量的硬编码方式。
- 与其他消息中间件支持的相似性
- 在很多方面与 Spring 框架中的 JMS(Java Message Service)支持以及 Spring AMQP(Advanced Message Queuing Protocol)中的 RabbitMQ 支持有相似之处,使得熟悉这些技术的开发者可以更容易地迁移到使用 Kafka 并利用 Spring 的集成。
项目地址: https://spring.io/projects/spring-kafka
3.1 测试环境搭建
框架版本说明:
- spring boot 3.3.4
- Java 17
操作步骤:
- 新建一个
spring boot
项目 - 引入
spring-kafka
依赖
xml
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
空跑一下项目,查看是否有问题.
3.2 KafkaTempalte发送消息
KafkaTemplate
包装了一个生产者,并提供了将数据发送到 Kafka 主题的便捷方法。下面的清单显示了KafkaTemplate
中的相关方法:
java
CompletableFuture<SendResult<K, V>> sendDefault(V data);
CompletableFuture<SendResult<K, V>> sendDefault(K key, V data);
CompletableFuture<SendResult<K, V>> sendDefault(Integer partition, K key, V data);
CompletableFuture<SendResult<K, V>> sendDefault(Integer partition, Long timestamp, K key, V data);
CompletableFuture<SendResult<K, V>> send(String topic, V data);
CompletableFuture<SendResult<K, V>> send(String topic, K key, V data);
CompletableFuture<SendResult<K, V>> send(String topic, Integer partition, K key, V data);
CompletableFuture<SendResult<K, V>> send(String topic, Integer partition, Long timestamp, K key, V data);
CompletableFuture<SendResult<K, V>> send(ProducerRecord<K, V> record);
CompletableFuture<SendResult<K, V>> send(Message<?> message);
Map<MetricName, ? extends Metric> metrics();
List<PartitionInfo> partitionsFor(String topic);
<T> T execute(ProducerCallback<K, V, T> callback);
<T> T executeInTransaction(OperationsCallback<K, V, T> callback);
// Flush the producer.
void flush();
interface ProducerCallback<K, V, T> {
T doInKafka(Producer<K, V> producer);
}
interface OperationsCallback<K, V, T> {
T doInOperations(KafkaOperations<K, V> operations);
}
这里需要注意的是:
- 在版本 3.0 中,以前返回
ListenableFuture
的方法已更改为返回CompletableFuture
。为了便于迁移,2.9 版本添加了一个方法usingCompletableFuture(),
该方法为CompletableFuture
返回类型提供了相同的方法;此方法不再可用。
java
@RestController
public class KafkaController {
private final KafkaTemplate<String, Object> kafkaTemplate;
public KafkaController(KafkaTemplate<String, Object> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
@GetMapping("/send")
public String sendMsg(String msg) {
CompletableFuture<SendResult<String, Object>> completableFuture
= kafkaTemplate.send(Constants.Kafka.TOPIC_NAME, msg);
completableFuture.whenComplete((result, ex) -> {
if (ex == null) {
System.out.println("发送成功");
} else {
System.out.println("发送失败");
}
});
return "发送成功!";
}
}
编写配置文件, 在application.yml
文件当中,配置kafka的生产者配置项.
yaml
spring:
application:
name: rj-spring-kafka-demo
kafka:
# 以逗号分隔的地址列表,用于建立与/域名Kafka集群的初始连接(kafka 默认的端口号为9092)
bootstrap-servers: kafka broker ip地址:9092
producer:
# 发生错误后,消息重发的次数。
retries: 3
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
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
listener:
# 在侦听器容器中运行的线程数。
concurrency: 5
# listener负责ack,每调用一次,就立即commit
ack-mode: manual_immediate
server:
port: 8080
打开浏览器,访问接口: localhost:8080/send?msg=你好
, 点击发送
在进入kafka容器, 通过命令行,进行消息的消费:
bash
root@acca0c42f22f:/opt/kafka/bin# ./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic rj-topic --from-beginning
hello,kafka
hello, java
hello
你好 # 刚才发送的消息,已经收到了
3.3 @KafkaListener 监听消息
@KafkaListener
注解用于将 Bean 方法指定为侦听器容器的侦听器。该 Bean 包装在一个 MessagingMessageListenerAdapter 配置了各种功能(例如转换器)中,以便在必要时转换数据以匹配方法参数。
java
@Component
@Slf4j
public class UserListener {
/**
* 监听消费消息
* @param msg
* @return
*/
@KafkaListener(groupId = "rj", topics = Constants.Kafka.TOPIC_NAME)
public CompletableFuture<String> listen(String msg){
log.info("receive msg: {}", msg);
return CompletableFuture.completedFuture(msg);
}
}
由于当前只有一个服务, 所以在配置文件当中,既要配置生产者,也要配置消费者,编写配置文件,在application.yml
文件当中,配置一下消费者,完整的配置文件如下所示:
yaml
spring:
application:
name: rj-spring-kafka-demo
kafka:
# 以逗号分隔的地址列表,用于建立与Kafka集群的初始连接(kafka 默认的端口号为9092)
bootstrap-servers: ip:9092
producer:
# 发生错误后,消息重发的次数。
retries: 3
# 当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
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:
# 自动提交的时间间隔 在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
listener:
# 在侦听器容器中运行的线程数。
concurrency: 5
# listener负责ack,每调用一次,就立即commit
ack-mode: manual_immediate
server:
port: 8080
启动服务,请求接口,观察控制台输出消息内容:
bash
2024-09-24T14:31:20.234+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ XNIO-1 task-2] o.a.k.clients.producer.ProducerConfig : ProducerConfig values:
acks = 1
auto.include.jmx.reporter = true
batch.size = 16384
bootstrap.servers = [ip:9092]
buffer.memory = 33554432
client.dns.lookup = use_all_dns_ips
client.id = rj-spring-kafka-demo-producer-1
compression.type = none
connections.max.idle.ms = 540000
delivery.timeout.ms = 120000
enable.idempotence = false
enable.metrics.push = true
interceptor.classes = []
key.serializer = class org.apache.kafka.common.serialization.StringSerializer
linger.ms = 0
max.block.ms = 60000
max.in.flight.requests.per.connection = 5
max.request.size = 1048576
metadata.max.age.ms = 300000
metadata.max.idle.ms = 300000
metric.reporters = []
metrics.num.samples = 2
metrics.recording.level = INFO
metrics.sample.window.ms = 30000
partitioner.adaptive.partitioning.enable = true
partitioner.availability.timeout.ms = 0
partitioner.class = null
partitioner.ignore.keys = false
receive.buffer.bytes = 32768
reconnect.backoff.max.ms = 1000
reconnect.backoff.ms = 50
request.timeout.ms = 30000
retries = 3
retry.backoff.max.ms = 1000
retry.backoff.ms = 100
sasl.client.callback.handler.class = null
sasl.jaas.config = null
sasl.kerberos.kinit.cmd = /usr/bin/kinit
sasl.kerberos.min.time.before.relogin = 60000
sasl.kerberos.service.name = null
sasl.kerberos.ticket.renew.jitter = 0.05
sasl.kerberos.ticket.renew.window.factor = 0.8
sasl.login.callback.handler.class = null
sasl.login.class = null
sasl.login.connect.timeout.ms = null
sasl.login.read.timeout.ms = null
sasl.login.refresh.buffer.seconds = 300
sasl.login.refresh.min.period.seconds = 60
sasl.login.refresh.window.factor = 0.8
sasl.login.refresh.window.jitter = 0.05
sasl.login.retry.backoff.max.ms = 10000
sasl.login.retry.backoff.ms = 100
sasl.mechanism = GSSAPI
sasl.oauthbearer.clock.skew.seconds = 30
sasl.oauthbearer.expected.audience = null
sasl.oauthbearer.expected.issuer = null
sasl.oauthbearer.jwks.endpoint.refresh.ms = 3600000
sasl.oauthbearer.jwks.endpoint.retry.backoff.max.ms = 10000
sasl.oauthbearer.jwks.endpoint.retry.backoff.ms = 100
sasl.oauthbearer.jwks.endpoint.url = null
sasl.oauthbearer.scope.claim.name = scope
sasl.oauthbearer.sub.claim.name = sub
sasl.oauthbearer.token.endpoint.url = null
security.protocol = PLAINTEXT
security.providers = null
send.buffer.bytes = 131072
socket.connection.setup.timeout.max.ms = 30000
socket.connection.setup.timeout.ms = 10000
ssl.cipher.suites = null
ssl.enabled.protocols = [TLSv1.2, TLSv1.3]
ssl.endpoint.identification.algorithm = https
ssl.engine.factory.class = null
ssl.key.password = null
ssl.keymanager.algorithm = SunX509
ssl.keystore.certificate.chain = null
ssl.keystore.key = null
ssl.keystore.location = null
ssl.keystore.password = null
ssl.keystore.type = JKS
ssl.protocol = TLSv1.3
ssl.provider = null
ssl.secure.random.implementation = null
ssl.trustmanager.algorithm = PKIX
ssl.truststore.certificates = null
ssl.truststore.location = null
ssl.truststore.password = null
ssl.truststore.type = JKS
transaction.timeout.ms = 60000
transactional.id = null
value.serializer = class org.apache.kafka.common.serialization.StringSerializer
2024-09-24T14:31:20.234+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ XNIO-1 task-2] o.a.k.c.t.i.KafkaMetricsCollector : initializing Kafka metrics collector
2024-09-24T14:31:20.244+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ XNIO-1 task-2] o.a.kafka.common.utils.AppInfoParser : Kafka version: 3.7.1
2024-09-24T14:31:20.244+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ XNIO-1 task-2] o.a.kafka.common.utils.AppInfoParser : Kafka commitId: e2494e6ffb89f828
2024-09-24T14:31:20.244+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ XNIO-1 task-2] o.a.kafka.common.utils.AppInfoParser : Kafka startTimeMs: 1727159480244
2024-09-24T14:31:20.269+08:00 INFO 22448 --- [rj-spring-kafka-demo] [demo-producer-1] org.apache.kafka.clients.Metadata : [Producer clientId=rj-spring-kafka-demo-producer-1] Cluster ID: Bd0lOF6VRimSuYcCCbfEVQ
2024-09-24T14:31:20.316+08:00 INFO 22448 --- [rj-spring-kafka-demo] [ntainer#0-0-C-1] com.rj.kafka.listener.UserListener : receive msg: 你好 # 接收到我们发送的消息了
3.4 小节
通过以上的学习,对于kafka的基本操作算是入门了.主要掌握发送消息、监听消息.
- 使用kafkaTemplate 进行消息的发送
- @KafkaListener 监听消息
这里需要注意的是, 发送消息的时候,返回值是: CompletableFuture
接口.
后续文章,我们继续研究一下kafka的发送的相关参数、消息确认、集群都相关知识点.