本文任务
一、Kafka服务批量启动函数封装
二、Kafka服务批量停止函数封装
三、Kafka服务状态批量检测函数封装
四、Kafka服务一键启停脚本主函数体实现
五、进一步抽象脚本,改进为通用的一键启停其他服务的脚本
核心知识点
知识点1:一键启停多主机集群服务实现
知识点2:服务状态检测的多种方式实现
知识点3:脚本内容抽象封装技巧
解决的问题
问题1:进程在,但是部分主机服务已僵死
问题2:一键管理你的生产环境服务。包括启动、停止、状态获取
问题3:服务运行报告生成,更细粒度检测你的集群服务稳定性
1 kafka一键启停脚本
1.1 脚本骨架搭建
function service_start
{
}
function service_stop
{
}
function service_status
{
}
function usage
{
}
case $1 in
start)
....
;;
stop)
....
;;
status)
....
;;
*)
usage
;;
esac
1.2 服务状态
service_status
函数的目的是检查给定主机上的 Kafka 服务是否正在运行。
这个函数会尝试通过 SSH 连接到指定的主机,并使用 jps | grep -w Kafka
命令来查找 Kafka 进程。该函数会进行五次尝试。
如果在每次尝试中都成功找到 Kafka 进程(返回码为0),则最终结果是 Kafka 在运行状态;否则就认为 Kafka 并未运行。
HOST_LIST="node01 node02 node03"
function service_status
{
status_idx=0
result=0
while [ $status_idx -lt 5 ];do
ssh -o StrictHostKeyChecking=no $1 "jps | grep -w Kafka" &>/dev/null
if [ $? -eq 0 ];then
result=`expr $result + 1`
fi
status_idx=`expr $status_idx + 1`
done
if [ $result -eq 5 ];then
return
fi
return 99
}
case $1 in
start)
service_start
;;
stop)
service_stop
;;
status)
for host in $HOST_LIST;do
service_status $host
if [ $? -eq 0 ];then
echo "kafka in $host is RUNNING"
else
echo "kafka in $host is STOPPED"
fi
done
;;
*)
usage
;;
esac
1.3 服务启动
- 遍历
HOST_LIST
,即 "node01 node02 node03" 中的每个节点。 - 对于每个主机 (
$host
):
-
- 打印开始启动 Kafka 的信息。
- 使用
service_status
函数检查 Kafka 是否已经在运行。 - 如果 Kafka 已经在运行,则打印一条信息表明 Kafka 已在该主机上运行。
- 如果 Kafka 没有运行:
-
-
- 通过 SSH 在远程主机上执行启动 Kafka 的命令。
- 然后进入一个五次的循环,每次循环使用
service_status
检查 Kafka 是否已经启动。 - 如果 Kafka 还未运行(
service_status
返回非零),则等待 3 秒后重新检查,直至五次尝试结束或 Kafka 启动成功。 - 如果五次尝试后 Kafka 仍未启动成功,则提示需要登录到对应的主机检查问题。
HOST_LIST="node01 node02 node03"
function service_start
{
for host in HOST_LIST;do echo "-------Now Begin To Start Kafka In host:host-------"
service_status $host
if [ $? -eq 0 ];then
echo "kafka in $host is already RUNNING"
else
echo "Now Kafka is STOPPED,start it...."
ssh -o StrictHostKeyChecking=no $host "/opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties"
index=0
while [ $index -lt 5 ];do
service_status $host
if [ $? -ne 0 ];then
echo "Kafka in $host is starting...Please wait...."
sleep 3
index=expr $index + 1
continue
else
echo "OK ... kafka in $host is RUNNING"
break
fi
done
if [ $index -eq 5 ];then
echo "sorry...kafka broker start failed...please login $host to check"
fi
fi
done
}
case $1 in
start)
service_start
;;
stop)
service_stop
;;
status)
for host in $HOST_LIST;do
service_status $host
if [ $? -eq 0 ];then
echo "kafka in $host is RUNNING"
else
echo "kafka in $host is STOPPED"
fi
done
;;
*)
usage
;;
esac
-
1.4 服务停止
是由启动模块修改而来,流程基本一样,只修改了stop字样和判断方式
-
如果返回值不等于
0
(即$? -ne 0
),表示 Kafka 服务已经停止,打印一条消息说明 Kafka 已经是停止状态。HOST_LIST="node01 node02 node03"
function service_stop
{
for host in HOST_LIST;do echo "-------Now Begin To Stop Kafka In host:host-------"
service_status $host
if [ $? -ne 0 ];then
echo "kafka in $host is already STOPPED"
else
echo "Now Kafka is RUNNING,stop it...."
ssh -o StrictHostKeyChecking=no $host "/opt/source/kafka/bin/kafka-server-stop.sh"
index=0
while [ $index -lt 5 ];do
service_status $host
if [ $? -eq 0 ];then
echo "Kafka in $host is starting...Please wait...."
sleep 3
index=expr $index + 1
continue
else
echo "OK ... kafka in $host is STOPPING"
break
fi
done
if [ $index -eq 5 ];then
echo "sorry...kafka broker stop failed...please login $host to check"
fi
fi
done
}
1.5 服务用法
function usage
{
cat << EOF
Usage1: sh $0 start # start kafka
Usage2: sh $0 stop # stop kafka
Usage3: sh $0 status # kafka status
EOF
}
2 通用一键启停服务脚本
2.1 检测服务状态是否正常
systemctl status <service>: 在使用 systemd 的系统中,这个命令用来查看服务的状态。
ps, top, htop: 这些命令可以用来查看系统运行的进程,从而判断某个服务是否活跃。
netstat 或 ss: 用于检查网络端口和连接,判断服务相关的端口是否在监听。
curl : 对于提供 HTTP 接口的服务,可以通过这些命令测试服务响应。
2.2 通用脚本
1.将原有的Kafka一键启动脚本改造为能够启停任何服务的通用脚本。
2.通过抽象监测进程、启动和停止服务的指令,使脚本具有更好的灵活性。
3.引入变量来保存状态监测、启动和停止服务的指令,便于根据需要更改。
STATUS_CMD="jps | grep -w Kafka"
START_CMD="/opt/source/kafka/bin/kafka-server-start.sh -daemon /opt/source/kafka/config/server.properties"
STOP_CMD="/opt/source/kafka/bin/kafka-server-stop.sh"
SERVICE_NAME="Kafka"
ssh -o StrictHostKeyChecking=no $host $START_CMD &> /dev/null
ssh -o StrictHostKeyChecking=no $host $STOP_CMD &> /dev/null
ssh -o StrictHostKeyChecking=no $1 $STATUS_CMD &>/dev/null
#将脚本中的kafka改为$SERVICE_NAME
如果需要启动别的服务,只需要修改前面定义的即可。
例如:启停zookeeper服务。
STATUS_CMD="jps | grep -w QuorumPeerMain"
START_CMD="/opt/source/zookeeper/bin/zkServer.sh start"
STOP_CMD="/opt/source/zookeeper/bin/zkServer.sh stop"
SERVICE_NAME="Zookeeper"
启停nginx:
SELF_PID=$$ #本脚本的pid
STATUS_CMD="ps -ef |grep nginx |grep -v grep |grep -v $SELF_PID" #去除干扰项
START_CMD="/usr/sbin/nginx"
STOP_CMD="/usr/sbin/nginx -s stop"
SERVICE_NAME="Nginx"
2.3 最终转化脚本成果展示
#!/bin/bash
#
HOST_LIST="node01 node02 node03"
SELF_PID=$$
STATUS_CMD=""
START_CMD=""
STOP_CMD=""
SERVICE_NAME=""
function service_start
{
for host in $HOST_LIST;do
echo "-------Now Begin To Start $SERVICE_NAME In host:$host-------"
service_status $host
if [ $? -eq 0 ];then
echo "$SERVICE_NAME in $host is already RUNNING"
else
echo "Now $SERVICE_NAME is STOPPED,start it...."
ssh -o StrictHostKeyChecking=no $host $START_CMD &> /dev/null
index=0
while [ $index -lt 5 ];do
service_status $host
if [ $? -ne 0 ];then
echo "$SERVICE_NAME in $host is starting...Please wait...."
sleep 3
index=`expr $index + 1`
continue
else
echo "OK ... $SERVICE_NAME in $host is RUNNING"
break
fi
done
if [ $index -eq 5 ];then
echo "sorry...$SERVICE_NAME broker start failed...please login $host to check"
fi
fi
done
}
function service_stop
{
for host in $HOST_LIST;do
echo "-------Now Begin To Stop $SERVICE_NAME In host:$host-------"
service_status $host
if [ $? -ne 0 ];then
echo "$SERVICE_NAME in $host is already STOPPED"
else
echo "Now $SERVICE_NAME is RUNNING,stop it...."
ssh -o StrictHostKeyChecking=no $host $STOP_CMD &> /dev/null
index=0
while [ $index -lt 5 ];do
service_status $host
if [ $? -eq 0 ];then
echo "$SERVICE_NAME in $host is stoping...Please wait...."
sleep 3
index=`expr $index + 1`
continue
else
echo "OK ... $SERVICE_NAME in $host is STOPPING"
break
fi
done
if [ $index -eq 5 ];then
echo "sorry...$SERVICE_NAME broker stop failed...please login $host to check"
fi
fi
done
}
function service_status
{
status_idx=0
result=0
while [ $status_idx -lt 5 ];do
ssh -o StrictHostKeyChecking=no $1 $STATUS_CMD &>/dev/null
if [ $? -eq 0 ];then
result=`expr $result + 1`
fi
status_idx=`expr $status_idx + 1`
done
if [ $result -eq 5 ];then
return
fi
return 99
}
function usage
{
cat << EOF
Usage1: sh $0 start # start $SERVICE_NAME
Usage2: sh $0 stop # stop $SERVICE_NAME
Usage3: sh $0 status # $SERVICE_NAME status
EOF
}
case $1 in
start)
service_start
;;
stop)
service_stop
;;
status)
for host in $HOST_LIST;do
service_status $host
if [ $? -eq 0 ];then
echo "$SERVICE_NAME in $host is RUNNING"
else
echo "$SERVICE_NAME in $host is STOPPED"
fi
done
;;
*)
usage
;;
esac