快速启动
定义与作用
本节完成 Kafka 的启动、第一条消息的发送与消费。这是每一个 Kafka 初学者的"Hello World"时刻——通过实际操作建立对"生产者→Broker→消费者"数据流的感性认识。
核心原理
Kafka 的启动流程(KRaft 模式):
完整示例
示例一:后台启动 Kafka 并验证
操作前环境:已完成 KRaft 格式化(参考 环境准备与安装.md)。
步骤:
cd /opt/kafka
# 1. 后台启动 Kafka
bin/kafka-server-start.sh -daemon config/kraft/server.properties
# 2. 等待 5 秒让 Kafka 完全启动
sleep 5
# 3. 验证进程存在
jps -l | grep Kafka
# 12345 kafka.Kafka
# 4. 查看启动日志(确认无 ERROR)
tail -30 /opt/kafka/logs/server.log
# ... [KafkaServer id=1] started (kafka.server.KafkaServer)
# ... Transition from STARTING to STARTED
操作后状态:
| 检查项 | 预期结果 |
|---|---|
| 进程 | kafka.Kafka 进程运行中 |
| 端口 | 9092 正在监听(`ss -tlnp |
| 日志 | 无 ERROR 级别日志,最后一行含 "started" |
示例二:发送与消费第一条消息
场景:使用 Kafka 自带的命令行工具,发送消息并在另一个终端消费。
操作前环境:Kafka 已启动,Topic 尚未创建。
步骤:
# ========== 终端 1:创建 Topic 并启动 Producer ==========
# 1. 创建名为 hello-world 的 Topic
bin/kafka-topics.sh --create \
--topic hello-world \
--bootstrap-server localhost:9092 \
--partitions 1 \
--replication-factor 1
# Created topic hello-world.
# 2. 启动 Console Producer(命令行生产者)
bin/kafka-console-producer.sh \
--topic hello-world \
--bootstrap-server localhost:9092
> Hello Kafka!
> 这是我的第一条消息
> {"user":"alice","action":"login","timestamp":1718208000}
# ========== 终端 2:启动 Consumer ==========
# 3. 启动 Console Consumer(从最早的消息开始消费)
bin/kafka-console-consumer.sh \
--topic hello-world \
--from-beginning \
--bootstrap-server localhost:9092
# Hello Kafka!
# 这是我的第一条消息
# {"user":"alice","action":"login","timestamp":1718208000}
操作前后对比:
| 阶段 | Topic 状态 | 消息数 |
|---|---|---|
| 操作前 | 不存在 | 0 |
--create 后 | 存在,1 分区,1 副本 | 0 |
| Producer 发送 3 条后 | 存在 | 3 |
| Consumer 消费后 | 存在 | 3(消息仍在,可重复消费) |
关键观察:Consumer 消费后消息仍然存在于 Kafka 中。这与 RabbitMQ(消费即删除)完全不同。可另开一个 Consumer 重新从 --from-beginning 消费,会再次看到相同消息。
启动脚本速查
| 脚本 | 用途 | 常用参数 |
|---|---|---|
kafka-server-start.sh | 启动 Broker | -daemon(后台运行) |
kafka-server-stop.sh | 停止 Broker | 无 |
kafka-topics.sh | Topic 管理 | --create / --list / --describe / --delete |
kafka-console-producer.sh | 命令行生产者 | --topic / --bootstrap-server |
kafka-console-consumer.sh | 命令行消费者 | --topic / --from-beginning / --group |
kafka-storage.sh | 存储格式化(KRaft) | random-uuid / format |
易错场景
易错 1:Producer 发送成功但 Consumer 看不到消息
现象:Producer 发送消息无报错,但 Consumer 无输出。
原因分析:
可能原因 1:Consumer 没有加 --from-beginning,默认只消费启动后的新消息。
可能原因 2:Consumer 和 Producer 连接了不同的 Bootstrap Server。
可能原因 3:Consumer 使用了与之前相同的 Group ID,且 offset 已提交到末尾。
诊断命令:
# 检查 Topic 是否存在且消息数 > 0
bin/kafka-run-class.sh kafka.tools.GetOffsetShell \
--topic hello-world --time -2 --bootstrap-server localhost:9092
# hello-world:0:0 ← 最早 offset 为 0
bin/kafka-run-class.sh kafka.tools.GetOffsetShell \
--topic hello-world --time -1 --bootstrap-server localhost:9092
# hello-world:0:3 ← 最新 offset 为 3,说明有 3 条消息
# 确认消息在 Kafka 中存在后,Consumer 加 --from-beginning 重试
易错 2:端口被占用
现象:
java.net.BindException: Address already in use
解决:
# 查找占用 9092 端口的进程
lsof -i :9092
# 或
ss -tlnp | grep 9092
kill <PID>
面试高频考点
Q:--from-beginning 的实际含义是什么?
A:它告诉 Consumer 将其 offset 重置到 earliest(最早可用消息),而不是默认的 latest(只消费新到达的消息)。这利用了 Kafka 的消息重放特性——消息不会因被消费而删除。在真实的 Consumer API 中对应 auto.offset.reset=earliest。