CentOS 系统上安装 Kafka基础环境【一】

76 阅读7分钟

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消息顺序消费。请大家关注公众号九逸编码】,我会同步到公众号。

image-20250803234830281.png

✅ 一、环境准备

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.propertiesproducer/consumer.properties 中统一设置
日志清理设置 log.retention.byteshours 防止磁盘爆满
JVM 参数修改 bin/kafka-server-start.sh 中的 KAFKA_HEAP_OPTS 调整堆内存
防火墙开放端口 90922181
sudo firewall-cmd --permanent --add-port=9092/tcp
sudo firewall-cmd --reload

🧩 八、常见问题排查

问题解决方案
Connection refused检查 ZooKeeper 和 Kafka 是否启动
消费者收不到消息检查 advertised.listeners IP 是否正确
消息太大被拒绝调整 message.max.bytesmax.request.size
启动报错 Address already in use端口被占用,lsof -i :9092 查看并 kill

📚 九、参考资料


✅ 总结

步骤内容
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 KafkaLombok(可选,用于简化代码)依赖。

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 完整 配置文件详解【二】

image-20250803234823248.png