Kafka 集群开机自启动配置指南

9 阅读7分钟

Kafka 集群开机自启动配置指南

概述

本文档描述如何通过 systemd 为 Kafka KRaft 三节点集群配置开机自启动服务。配置完成后,三台机器在重启后 Kafka 服务将自动启动,无需人工干预。

集群节点信息

节点名称IP用户SSH端口
node1kafka01192.168.1.1root22(远程访问)
node2kafka02192.168.1.2root22
node3kafka03192.168.1.3root22

服务文件位置

/etc/systemd/system/kafka.service

三台机器均使用完全相同的服务文件内容。


systemd 服务文件

完整内容

文件路径: /etc/systemd/system/kafka.service

[Unit]
Description=Apache Kafka Server (KRaft mode)
Documentation=https://kafka.apache.org/
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
User=root
Environment="JAVA_HOME=/usr/local/java/jdk-21.0.10+7"
Environment="KAFKA_OPTS=-Djava.security.auth.login.config=/usr/local/kafka/config/kafka_server_jaas.conf"
Environment="KAFKA_HEAP_OPTS=-Xmx1G -Xms1G"
ExecStart=/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/kraft/server.properties
ExecStop=/usr/local/kafka/bin/kafka-server-stop.sh
Restart=on-failure
RestartSec=10
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target

配置项说明

[Unit] 部分
配置项值说明
DescriptionApache Kafka Server (KRaft mode)服务描述信息
Documentationkafka.apache.org/官方文档链接
Afternetwork-online.target在网络服务就绪后启动
Wantsnetwork-online.target依赖网络在线目标
[Service] 部分
配置项值说明
TypeforkingKafka 以 daemon 模式启动,会 fork 子进程到后台
Userroot以 root 用户运行
Environment (JAVA_HOME)/usr/local/java/jdk-21.0.10+7Java 21 安装路径
Environment (KAFKA_OPTS)-Djava.security.auth.login.config=...JAAS 认证配置文件路径(SASL 认证必需)
Environment (KAFKA_HEAP_OPTS)-Xmx1G -Xms1GJVM 堆内存配置(1GB)
ExecStartkafka-server-start.sh -daemon ...启动命令,使用 -daemon 后台运行
ExecStopkafka-server-stop.sh停止命令
Restarton-failure进程异常退出时自动重启
RestartSec10重启前等待 10 秒
LimitNOFILE100000最大文件描述符数
[Install] 部分
配置项值说明
WantedBymulti-user.target注册到多用户运行级别(开机自动启动)

部署步骤

前提条件

  • ✅ 三台机器均已安装 OpenJDK 21(路径:/usr/local/java/jdk-21.0.10+7)
  • ✅ 三台机器均已安装 Kafka(路径:/usr/local/kafka)
  • ✅ 三台机器均已配置 server.properties(含 controller.quorum.voters、advertised.listeners 等)
  • ✅ 三台机器均已创建 kafka_server_jaas.conf(JAAS 认证配置)
  • ✅ 三台机器均已完成 KRaft 格式化(Cluster UUID 一致)
  • ✅ 本机到远程机器 SSH 免密已配置(端口 22)

步骤 1:在本机创建 systemd 服务文件

# 创建 kafka.service 文件
cat > /etc/systemd/system/kafka.service << 'EOF'
[Unit]
Description=Apache Kafka Server (KRaft mode)
Documentation=https://kafka.apache.org/
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
User=root
Environment="JAVA_HOME=/usr/local/java/jdk-21.0.10+7"
Environment="KAFKA_OPTS=-Djava.security.auth.login.config=/usr/local/kafka/config/kafka_server_jaas.conf"
Environment="KAFKA_HEAP_OPTS=-Xmx1G -Xms1G"
ExecStart=/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/kraft/server.properties
ExecStop=/usr/local/kafka/bin/kafka-server-stop.sh
Restart=on-failure
RestartSec=10
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target
EOF

# 验证文件内容
cat /etc/systemd/system/kafka.service

步骤 2:验证启用状态

# 本机验证
systemctl is-enabled kafka.service

# 远程 kafka02 验证
ssh -p 22 root@192.168.1.2 "systemctl is-enabled kafka.service"

# 远程 kafka03 验证
ssh -p 22 root@192.168.1.3 "systemctl is-enabled kafka.service"

预期结果:三台机器均输出 enabled。


服务管理命令

启动集群

# 1. 启动本机 kafka01
systemctl start kafka.service

# 等待 node1 启动完成
sleep 10

# 2. 启动远程 kafka02
ssh -p 22 root@192.168.1.2 "systemctl start kafka.service"

# 等待 node2 启动完成
sleep 10

# 3. 启动远程 kafka03
ssh -p 22 root@192.168.1.3 "systemctl start kafka.service"

# 等待集群完成 Controller 选举
sleep 15

启动顺序:建议按 node1 → node2 → node3 的顺序依次启动,减少 Raft 选举抖动。

停止集群

# 1. 停止远程 kafka03
ssh -p 22 root@192.168.1.3 "systemctl stop kafka.service"

sleep 5

# 2. 停止远程 kafka02
ssh -p 22 root@192.168.1.2 "systemctl stop kafka.service"

sleep 5

# 3. 停止本机 kafka01
systemctl stop kafka.service

停止顺序:建议先停远程节点再停本机,与本机管理脚本保持一致。

重启集群

# 重启本机 kafka01
systemctl restart kafka.service

# 重启远程 kafka02
ssh -p 22 root@192.168.1.2 "systemctl restart kafka.service"

# 重启远程 kafka03
ssh -p 22 root@192.168.1.3 "systemctl restart kafka.service"

查看服务状态

# 本机服务状态
systemctl status kafka.service

# 远程 kafka02 服务状态
ssh -p 22 root@192.168.1.2 "systemctl status kafka.service"

# 远程 kafka03 服务状态
ssh -p 22 root@192.168.1.3 "systemctl status kafka.service"

预期结果:服务状态为 active (running),显示进程 PID 和启动时间。

查看服务日志

# 本机 systemd 日志(最近 50 行)
journalctl -u kafka.service -n 50 --no-pager

# 本机实时跟踪日志
journalctl -u kafka.service -f

# 远程 kafka02 systemd 日志
ssh -p 22 root@192.168.1.2 "journalctl -u kafka.service -n 50 --no-pager"

# 远程 kafka03 systemd 日志
ssh -p 22 root@192.168.1.3 "journalctl -u kafka.service -n 50 --no-pager"

禁用/启用开机自启动

# 禁用开机自启动(本机)
systemctl disable kafka.service

# 重新启用开机自启动(本机)
systemctl enable kafka.service

# 远程机器同理
ssh -p 22 root@192.168.1.2 "systemctl disable kafka.service"
ssh -p 22 root@192.168.1.2 "systemctl enable kafka.service"

集群启动后验证

1. 检查 Kafka 进程

# 本机进程
jps -l | grep kafka

# 远程 kafka02 进程
ssh -p 22 root@192.168.1.2 "jps -l | grep kafka"

# 远程 kafka03 进程
ssh -p 22 root@192.168.1.3 "jps -l | grep kafka"

预期结果:每台机器各 1 个 kafka.Kafka 进程。

2. 检查端口监听

# 本机端口
ss -tlnp | grep -E '9092|9093'

# 远程 kafka02 端口
ssh -p 22 root@192.168.1.2 "ss -tlnp | grep -E '9092|9093'"

# 远程 kafka03 端口
ssh -p 22 root@192.168.1.3 "ss -tlnp | grep -E '9092|9093'"

预期结果:每台机器监听 9092(Broker)和 9093(Controller)两个端口。

3. 检查集群仲裁状态

/usr/local/kafka/bin/kafka-metadata-quorum.sh \
  --bootstrap-server 192.168.1.1:9092 \
  --command-config /usr/local/kafka/config/kafka_client_sasl.properties \
  describe --status

预期结果:显示 Leader 和 Follower 节点正常,集群仲裁稳定。


开机自启动验证

方法一:重启机器验证(推荐)

# 重启本机 kafka01
reboot

# 等待机器重新上线后,验证 Kafka 服务状态
systemctl status kafka.service

# 查看启动日志
journalctl -u kafka.service --since "5 min ago"

注意:重启本机后需等待约 30-60 秒让服务自动启动。可通过另一台机器 SSH 验证。

方法二:不重启验证(模拟)

# 检查服务是否已注册为开机启动
systemctl is-enabled kafka.service

# 检查服务依赖关系
systemctl list-dependencies kafka.service

# 模拟启动流程(不实际启动)
systemctl start kafka.service --no-block

一键启动/停止脚本(systemd 版)

一键启动脚本

文件路径: /root/start-cluster-systemd.sh

#!/bin/bash
# Kafka KRaft 多机集群一键启动脚本(systemd 版)

NODE2_HOST="root@192.168.1.2"
NODE3_HOST="root@192.168.1.3"
SSH_OPTS="-p 22"
LOG_FILE=/root/kafka-cluster-start.log

echo "========================================" | tee $LOG_FILE
echo "Kafka KRaft 多机集群启动(systemd)" | tee -a $LOG_FILE
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" | tee -a $LOG_FILE
echo "========================================" | tee -a $LOG_FILE

# 启动本机 kafka01
echo "启动 kafka01 (192.168.1.1)..." | tee -a $LOG_FILE
systemctl start kafka.service
if [ $? -eq 0 ]; then
  echo "  kafka01 启动命令已发送" | tee -a $LOG_FILE
else
  echo "  kafka01 启动失败!" | tee -a $LOG_FILE
  exit 1
fi
sleep 10

# 启动远程 kafka02
echo "启动 kafka02 (192.168.1.2)..." | tee -a $LOG_FILE
ssh $SSH_OPTS $NODE2_HOST "systemctl start kafka.service"
if [ $? -eq 0 ]; then
  echo "  kafka02 启动命令已发送" | tee -a $LOG_FILE
else
  echo "  kafka02 启动失败!" | tee -a $LOG_FILE
  exit 1
fi
sleep 10

# 启动远程 kafka03
echo "启动 kafka03 (192.168.1.3)..." | tee -a $LOG_FILE
ssh $SSH_OPTS $NODE3_HOST "systemctl start kafka.service"
if [ $? -eq 0 ]; then
  echo "  kafka03 启动命令已发送" | tee -a $LOG_FILE
else
  echo "  kafka03 启动失败!" | tee -a $LOG_FILE
  exit 1
fi

# 等待集群完成 Controller 选举
echo "等待 Controller 选举完成..." | tee -a $LOG_FILE
sleep 15

# 验证启动结果
echo "" | tee -a $LOG_FILE
echo "=== 服务状态检查 ===" | tee -a $LOG_FILE
echo "kafka01: $(systemctl is-active kafka.service)" | tee -a $LOG_FILE
echo "kafka02: $(ssh $SSH_OPTS $NODE2_HOST 'systemctl is-active kafka.service')" | tee -a $LOG_FILE
echo "kafka03: $(ssh $SSH_OPTS $NODE3_HOST 'systemctl is-active kafka.service')" | tee -a $LOG_FILE

echo "" | tee -a $LOG_FILE
echo "=== 集群仲裁状态 ===" | tee -a $LOG_FILE
/usr/local/kafka/bin/kafka-metadata-quorum.sh \
  --bootstrap-server 192.168.1.1:9092 \
  --command-config /usr/local/kafka/config/kafka_client_sasl.properties \
  describe --status | tee -a $LOG_FILE

echo "" | tee -a $LOG_FILE
echo "集群启动完成,日志已保存至 $LOG_FILE"

赋予执行权限:

chmod +x /root/start-cluster-systemd.sh

一键停止脚本

文件路径: /root/stop-cluster-systemd.sh

#!/bin/bash
# Kafka KRaft 多机集群一键停止脚本(systemd 版)

NODE2_HOST="root@192.168.1.2"
NODE3_HOST="root@192.168.1.3"
SSH_OPTS="-p 22"
LOG_FILE=/root/kafka-cluster-stop.log

echo "========================================" | tee $LOG_FILE
echo "Kafka KRaft 多机集群停止(systemd)" | tee -a $LOG_FILE
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" | tee -a $LOG_FILE
echo "========================================" | tee -a $LOG_FILE

# 停止远程 kafka03
echo "停止 kafka03 (192.168.1.3)..." | tee -a $LOG_FILE
ssh $SSH_OPTS $NODE3_HOST "systemctl stop kafka.service"
echo "  kafka03 停止命令已发送" | tee -a $LOG_FILE
sleep 5

# 停止远程 kafka02
echo "停止 kafka02 (192.168.1.2)..." | tee -a $LOG_FILE
ssh $SSH_OPTS $NODE2_HOST "systemctl stop kafka.service"
echo "  kafka02 停止命令已发送" | tee -a $LOG_FILE
sleep 5

# 停止本机 kafka01
echo "停止 kafka01 (192.168.1.1)..." | tee -a $LOG_FILE
systemctl stop kafka.service
echo "  kafka01 停止命令已发送" | tee -a $LOG_FILE

# 等待进程退出
sleep 10

# 最终状态检查
echo "" | tee -a $LOG_FILE
echo "=== 最终服务状态 ===" | tee -a $LOG_FILE
echo "kafka01: $(systemctl is-active kafka.service)" | tee -a $LOG_FILE
echo "kafka02: $(ssh $SSH_OPTS $NODE2_HOST 'systemctl is-active kafka.service')" | tee -a $LOG_FILE
echo "kafka03: $(ssh $SSH_OPTS $NODE3_HOST 'systemctl is-active kafka.service')" | tee -a $LOG_FILE

echo "" | tee -a $LOG_FILE
echo "集群停止完成,日志已保存至 $LOG_FILE"

赋予执行权限:

chmod +x /root/stop-cluster-systemd.sh

常见问题排查

Q1: 开机后 Kafka 未自动启动

排查步骤:

# 1. 检查服务是否已启用
systemctl is-enabled kafka.service

# 2. 检查服务状态
systemctl status kafka.service

# 3. 查看 systemd 启动日志
journalctl -u kafka.service --since "1 hour ago"

# 4. 检查 Kafka 日志
tail -100 /usr/local/kafka/logs/server.log

常见原因:

  • 服务未执行 systemctl enable(仅 start 不会开机自启)
  • JAVA_HOME 路径不正确(systemd 环境不加载 ~/.bashrc)
  • server.properties 配置错误
  • 数据目录权限不足
  • 网络未就绪就开始启动(检查 After=network-online.target)

Q2: 服务启动后立即退出

# 查看详细错误日志
journalctl -u kafka.service -n 50 --no-pager

# 手动启动测试(绕过 systemd)
export JAVA_HOME=/usr/local/java/jdk-21.0.10+7
export KAFKA_OPTS="-Djava.security.auth.login.config=/usr/local/kafka/config/kafka_server_jaas.conf"
/usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/kraft/server.properties

Q3: Restart=on-failure 未生效

# 检查服务重启次数
systemctl show kafka.service -p NRestarts

# 检查 Restart 配置
systemctl show kafka.service -p Restart

# 查看重启日志
journalctl -u kafka.service | grep -i "restart\|start\|stop"

Q4: 修改了 server.properties 后需要重新加载

# systemd 服务文件修改后需要 daemon-reload
systemctl daemon-reload

# server.properties 修改后只需重启服务(无需 daemon-reload)
systemctl restart kafka.service