Kafka 安装步骤的全面整理、优化与丰富,适用于在 CentOS 系统上安装 Kafka 3.9.0(kafka_2.12-3.9.0),并使用其内置 ZooKeeper(推荐用于开发/测试环境)。该文档结构清晰、步骤完整,适合初学者和运维人员参考。
🚀 Apache Kafka 单机部署指南(含内置 ZooKeeper)
版本:
kafka_2.12-3.9.0
系统:CentOS 7/8/Stream
适用场景:开发、测试、学习环境
说明:Kafka 2.8+ 版本开始支持 KRaft 模式(无 ZooKeeper),但本教程使用 内置 ZooKeeper 快速搭建,便于入门。
本次搭建基础环境,主要是为了保证kafka如何顺序消费场景演示,还如何在消费端,生产端,保证kafka消息顺序消费。请大家关注公众号【九逸编码】,我会同步到公众号。
✅ 一、环境准备
1. 检查 Java 环境
Kafka 基于 Java 开发,需先安装 JDK 8 或 11(推荐 OpenJDK)。
java -version
若未安装,请执行:
sudo yum install -y java-11-openjdk-devel
验证安装成功后,设置 JAVA_HOME(可选,但建议):
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
💡 提示:可将上述两行写入
~/.bashrc或/etc/profile永久生效。
📦 二、下载并解压 Kafka
进入工作目录,下载 Kafka 3.9.0 版本:
cd /app/
# 下载 Kafka(请确认最新链接)
wget https://downloads.apache.org/kafka/3.9.0/kafka_2.12-3.9.0.tgz
# 解压
tar -xzf kafka_2.12-3.9.0.tgz
# 重命名便于管理
mv kafka_2.12-3.9.0 kafka
🔗 官网地址:kafka.apache.org/downloads
🐻 三、配置并启动内置 ZooKeeper
Kafka 3.x 版本仍默认携带 ZooKeeper,可用于单机部署。
1. 创建 ZooKeeper 数据和日志目录
mkdir -p /app/zookeeper/data
2. 配置 ZooKeeper
Kafka 自带的 ZooKeeper 配置文件位于:
config/zookeeper.properties
编辑该文件:
vim config/zookeeper.properties
修改或确认以下内容:
# ZooKeeper 数据存储目录
dataDir=/app/zookeeper/data
# 客户端连接端口
clientPort=2181
# 限制最大客户端连接数
maxClientCnxns=60
# 日志清理间隔(可选)
tickTime=2000
✅ 注意:无需额外安装 ZooKeeper,Kafka 内置即可使用。
3. 启动 ZooKeeper
nohup bin/zookeeper-server-start.sh config/zookeeper.properties &
# 查看是否启动成功
ps aux | grep zookeeper
🔍 日志路径:
nohup.out或查看logs/zookeeper-server*.log
🐘 四、配置并启动 Kafka Broker
1. 创建 Kafka 数据目录
mkdir -p /app/kafka/data/kafka-logs
2. 编辑 Kafka 配置文件
vim config/server.properties
关键配置如下:
# Broker 唯一标识(集群中不能重复)
broker.id=1
# 监听地址:对外暴露的接口
listeners=PLAINTEXT://0.0.0.0:9092
# 外部客户端连接地址(根据实际 IP 修改)
advertised.listeners=PLAINTEXT://192.168.254.90:9092
# 协议映射
listener.security.protocol.map=PLAINTEXT:PLAINTEXT
# 日志存储路径
log.dirs=/app/kafka/data/kafka-logs
# ZooKeeper 连接地址
zookeeper.connect=localhost:2181
# 可选:数据保留策略(默认 7 天)
log.retention.hours=168
# 单条消息最大大小(1GB,按需调整)
message.max.bytes=1073741824
socket.request.max.bytes=1073741824
# Producer 配置(在 producer.properties 中也可设置)
# max.request.size=1073741824
# Consumer 配置
# max.partition.fetch.bytes=1073741824
📌 注意:
advertised.listeners必须是外部可访问的 IP 或域名。- 若为本地测试,可设为
localhost。
3. 启动 Kafka Broker
nohup bin/kafka-server-start.sh config/server.properties &
# 检查进程
ps aux | grep kafka
✅ 成功标志:日志中出现
Kafka Server started。
🧪 五、创建 Topic 并测试收发消息
1. 创建 Topic
bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--replication-factor 1 \
--partitions 1 \
--topic testa
⚠️ 注意:Kafka 3.0+ 推荐使用
--bootstrap-server而非--zookeeper。
2. 查看 Topic 列表
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
3. 启动生产者(Producer)
bin/kafka-console-producer.sh \
--bootstrap-server 192.168.254.90:9092 \
--topic testa
输入任意消息,如:
Hello Kafka!
This is a test message.
💬 提示:每行一条消息。
4. 启动消费者(Consumer)
打开新终端,启动消费者:
# 从头开始消费
bin/kafka-console-consumer.sh \
--bootstrap-server 192.168.254.90:9092 \
--topic testa \
--from-beginning
或指定消费者组:
bin/kafka-console-consumer.sh \
--bootstrap-server 192.168.254.90:9092 \
--topic testa \
--consumer-property group.id=test_group_1
✅ 预期结果:消费者能实时收到生产者发送的消息。
🛑 六、停止服务
1. 停止 Kafka
bin/kafka-server-stop.sh
2. 停止 ZooKeeper
bin/zookeeper-server-stop.sh
💡 也可以使用
kill命令终止进程。
🔐 七、安全与调优建议(可选)
| 项目 | 建议 |
|---|---|
| 消息大小限制 | 在 server.properties 和 producer/consumer.properties 中统一设置 |
| 日志清理 | 设置 log.retention.bytes 和 hours 防止磁盘爆满 |
| JVM 参数 | 修改 bin/kafka-server-start.sh 中的 KAFKA_HEAP_OPTS 调整堆内存 |
| 防火墙 | 开放端口 9092 和 2181 |
sudo firewall-cmd --permanent --add-port=9092/tcp
sudo firewall-cmd --reload
🧩 八、常见问题排查
| 问题 | 解决方案 |
|---|---|
Connection refused | 检查 ZooKeeper 和 Kafka 是否启动 |
| 消费者收不到消息 | 检查 advertised.listeners IP 是否正确 |
| 消息太大被拒绝 | 调整 message.max.bytes 和 max.request.size |
启动报错 Address already in use | 端口被占用,lsof -i :9092 查看并 kill |
📚 九、参考资料
- Kafka 官网:kafka.apache.org
- 下载页面:kafka.apache.org/downloads
- 快速入门:kafka.apache.org/quickstart
✅ 总结
| 步骤 | 内容 |
|---|---|
| 1 | 安装 Java |
| 2 | 下载并解压 Kafka |
| 3 | 配置并启动 ZooKeeper |
| 4 | 配置并启动 Kafka Broker |
| 5 | 创建 Topic 并测试生产/消费 |
| 6 | 正常关闭服务 |
✅ 本方案适用于 学习、开发、测试环境。
🚨 生产环境建议使用 KRaft 模式(无 ZooKeeper)或独立 ZooKeeper 集群,以提高可用性和性能。
十. 创建一个新的 Spring Boot 项目
Spring Boot 应用程序示例,演示如何集成 Kafka 进行消息的生产和消费,展示了如何发送和接收消息。
你可以使用 Spring Initializr 来快速生成一个新的 Spring Boot 项目,选择 Maven 作为构建工具,并添加 Spring for Apache Kafka 和 Lombok(可选,用于简化代码)依赖。
1. 配置 application.yml
在 src/main/resources/application.yml 中添加 Kafka 相关的配置:
spring:
kafka:
bootstrap-servers: 192.168.254.90:9092
consumer:
group-id: demo-group
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
<!-- Spring Kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
2. 创建生产者服务
创建一个生产者服务类 KafkaProducerService.java:
import org.example.kafkaorderprocessing.model.Order;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
/**
*@BelongsProject: kafka-order-processing
*@BelongsPackage: org.example.kafkaorderprocessing.service
*@Author: 九逸
*@Description: TODO
*@Version: 1.0
*/
@Service
public class OrderProducerService {
private final KafkaTemplate<String, Order> kafkaTemplate;
public OrderProducerService(KafkaTemplate<String, Order> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void sendOrder(String userId, Order order) {
// 使用 userId 作为 key,确保同一用户的消息进入同一分区
kafkaTemplate.send("orders-topic", userId, order);
System.out.println("✅ 已发送: userId=" + userId + ", order=" + order.getProductId());
}
}
3. 创建消费者监听器
接下来,创建一个消费者监听器 KafkaConsumerListener.java:
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.example.kafkaorderprocessing.model.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Service;
/**
*@BelongsProject: kafka-order-processing
*@BelongsPackage: org.example.kafkaorderprocessing.consumer
*@Author: 九逸
*@Description: TODO
*@Version: 1.0
*/
@Service
public class OrderConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(OrderConsumer.class);
@KafkaListener(topics = "orders-topic", groupId = "order-group")
public void consume(Order order) {
System.out.println("✅ 收到订单: " + order.getUserId() + " - " + order.getProductId());
}
}
4. 编写控制器来触发消息发送
为了方便测试,我们可以编写一个简单的 REST 控制器来发送消息:
import org.example.kafkaorderprocessing.model.Order;
import org.example.kafkaorderprocessing.service.OrderProducerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
*@BelongsProject: kafka-order-processing
*@BelongsPackage: org.example.kafkaorderprocessing.controller
*@Author: 九逸
*@Description: TODO
*@Version: 1.0
*/
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderProducerService orderProducerService;
/**
* 测试接口:发送一个订单到 Kafka
*/
@PostMapping
public String sendOrder(@RequestBody Order order) {
try {
// 使用 userId 作为 key
orderProducerService.sendOrder(order.getUserId(), order);
return "🎉 已成功发送到 Kafka: " + order.getUserId() + " - " + order.getProductId();
} catch (Exception e) {
e.printStackTrace();
return "❌ 发送失败: " + e.getMessage();
}
}
/**
* 健康检查接口
*/
@GetMapping("/health")
public String health() {
return "✅ Kafka Producer 服务正常运行!";
}
}
5. 启动类
确保你的主应用程序类如下所示,包含必要的注解:
@SpringBootApplication
public class KafkaOrderProcessingApplication {
public static void main(String[] args) {
SpringApplication.run(KafkaOrderProcessingApplication.class, args);
}
}
6. KafkaConfig配置文件
package org.example.kafkaorderprocessing.config;
import org.apache.kafka.clients.admin.NewTopic;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.example.kafkaorderprocessing.model.Order;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.support.serializer.JsonSerializer;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class KafkaConfig {
@Value("${spring.kafka.bootstrap-servers}")
private String bootstrapServers;
@Bean
public ProducerFactory<String, Order> producerFactory() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(configProps);
}
@Bean
public KafkaTemplate<String, Order> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@Bean
public NewTopic createOrdersTopic() {
return new NewTopic("orders-topic", 3, (short) 1); // 3 partitions for example
}
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private String userId;
private String productId;
private int quantity;
}
7. 测试
启动 Kafka 和 ZooKeeper(如果你还没有启动的话),然后运行 Spring Boot 应用程序。通过访问以下 URL 发送消息:
访问:http://localhost:8080/api/orders
{
"userId": "user1",
"productId": "productA",
"quantity": 1
}
你应该能在控制台看到类似如下的输出:
✅ 已发送: userId=user1, order=productA
✅ 收到 Received Message: Key = user1, Value = Order(userId=user1, productId=productA, quantity=1)
这样,你就完成了一个简单的 Spring Boot 集成 Kafka 的示例。这个例子展示了如何发送和接收字符串类型的消息。根据实际需求,你可以进一步扩展此示例,例如处理更复杂的数据类型、实现错误处理逻辑等。
基础环境搭建好了,后续我会发布,kafka如何保证顺序消费场景演示,还如何在消费端,生产端,保证kafka消息顺序消费。请大家关注公众号【九逸编码】,我会同步到公众号。
往期内容 rsync + sersync 实现文件实时同步的完整配置详解【一】 rsyncd.conf、confxml.xml 完整 配置文件详解【二】