You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash脚本自动关闭本地Kafka集群?

本地Kafka集群自动化关闭解决方案

核心问题原因

你记录的PID是启动脚本(如kafka-server-start.sh)的父进程ID,但这类脚本会fork出JVM子进程实际运行Kafka服务。仅杀死父进程不会终止子进程,导致集群无法彻底关闭,这就是你看到多个关联PID的原因。

方法一:使用Kafka官方停止脚本(最可靠)

Kafka自带配套的停止脚本,能自动识别对应配置的进程并终止,无需手动管理PID。

关闭脚本代码

#!/bin/bash

KAFKA_SERVER_DIR="./kafka-3.7.0-src"
cd "$KAFKA_SERVER_DIR" || exit

# 关闭两个Kafka Broker
echo "Stopping Kafka brokers..."
bin/kafka-server-stop.sh config/server.properties
bin/kafka-server-stop.sh config/server1.properties

# 关闭Zookeeper
echo "Stopping Zookeeper..."
bin/zookeeper-server-stop.sh config/zookeeper.properties

# 可选:清理集群临时数据目录
rm -rf /tmp/kafka-logs /tmp/kafka-logs1 /tmp/zookeeper /tmp/kraft-combined-logs

方法二:改进启动脚本,记录进程组ID并批量终止

如果需要自定义进程管理,可记录每个服务的进程组ID,通过杀死整个进程组来彻底终止所有关联进程。

改进后的启动脚本

#!/bin/bash

KAFKA_SERVER_DIR="./kafka-3.7.0-src"
cd "$KAFKA_SERVER_DIR" || exit
PID_FILE="kafka_pids.txt"
PGID_FILE="kafka_pgids.txt"

# 清理旧数据和记录文件
rm -rf /tmp/kafka-logs /tmp/kafka-logs1 /tmp/zookeeper /tmp/kraft-combined-logs
rm -f "$PID_FILE" "$PGID_FILE"

# 启动Zookeeper并记录进程组ID
start_zookeeper() {
    echo "Starting Kafka Zookeeper..."
    bin/zookeeper-server-start.sh config/zookeeper.properties
}
start_zookeeper &
ZK_PID=$!
ZK_PGID=$(ps -o pgid= -p $ZK_PID | grep -o '[0-9]*')
echo "$ZK_PID $ZK_PGID" >> "$PID_FILE"
echo "$ZK_PGID" >> "$PGID_FILE"
sleep 1

# 启动第一个Broker
create_broker() {
    local config_file="$1"
    echo "Creating Kafka broker with config $config_file "
    bin/kafka-server-start.sh "$config_file"
}
create_broker "config/server.properties" &
BROKER1_PID=$!
BROKER1_PGID=$(ps -o pgid= -p $BROKER1_PID | grep -o '[0-9]*')
echo "$BROKER1_PID $BROKER1_PGID" >> "$PID_FILE"
echo "$BROKER1_PGID" >> "$PGID_FILE"
sleep 2

# 启动第二个Broker
create_broker "config/server1.properties" &
BROKER2_PID=$!
BROKER2_PGID=$(ps -o pgid= -p $BROKER2_PID | grep -o '[0-9]*')
echo "$BROKER2_PID $BROKER2_PGID" >> "$PID_FILE"
echo "$BROKER2_PGID" >> "$PGID_FILE"
sleep 2

# 创建Topic(该进程执行后自动退出,无需记录)
make_topic() {
    local topic_name="$1"
    local replication_factor="$2"
    local num_partitions="$3"
    bin/kafka-topics.sh --create --topic "$topic_name" --bootstrap-server localhost:9092 --replication-factor $replication_factor --partitions $num_partitions
}
make_topic "test_topic" 2 3 > make_topic_error.log &

对应的关闭脚本

#!/bin/bash

KAFKA_SERVER_DIR="./kafka-3.7.0-src"
cd "$KAFKA_SERVER_DIR" || exit
PGID_FILE="kafka_pgids.txt"

if [ -f "$PGID_FILE" ]; then
    echo "Stopping Kafka cluster..."
    # 遍历进程组ID,先发送终止信号,再强制清理残留进程
    while read -r PGID; do
        if [ -n "$PGID" ]; then
            echo "Killing process group $PGID..."
            kill -TERM -- -$PGID
            sleep 1
            kill -KILL -- -$PGID 2>/dev/null
        fi
    done < "$PGID_FILE"
    # 清理记录文件和临时数据
    rm -f "$PGID_FILE" "$PID_FILE"
    rm -rf /tmp/kafka-logs /tmp/kafka-logs1 /tmp/zookeeper /tmp/kraft-combined-logs
else
    echo "No running Kafka cluster detected (missing PGID file)."
fi

方法三:通过端口查找进程并终止

如果不想修改启动脚本,可根据服务端口直接查找并杀死进程(需确保端口未被其他进程占用):

#!/bin/bash

# 关闭Zookeeper(默认端口2181)
echo "Stopping Zookeeper..."
lsof -i :2181 | grep LISTEN | awk '{print $2}' | xargs kill -TERM
sleep 1
lsof -i :2181 | grep LISTEN | awk '{print $2}' | xargs kill -KILL 2>/dev/null

# 关闭Kafka Broker(默认端口9092、9093)
echo "Stopping Kafka brokers..."
lsof -i :9092,:9093 | grep LISTEN | awk '{print $2}' | xargs kill -TERM
sleep 1
lsof -i :9092,:9093 | grep LISTEN | awk '{print $2}' | xargs kill -KILL 2>/dev/null

# 清理临时数据
rm -rf /tmp/kafka-logs /tmp/kafka-logs1 /tmp/zookeeper /tmp/kraft-combined-logs

内容的提问来源于stack exchange,提问作者SarthakSin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 02:26:03