设计思路
- 服务依赖关系表示:使用一个数据结构(如关联数组)来存储每个服务及其依赖的服务。
- 启动顺序确定:根据依赖关系确定服务的启动顺序,先启动没有依赖的服务,再启动依赖这些服务的其他服务。
- 监控与重启:使用
while true
循环不断监控每个服务的运行状态,一旦发现服务停止,尝试重启该服务及其依赖的服务。
- 错误处理:记录重启失败的次数,达到一定次数后记录日志并通过邮件等方式通知管理员。
关键代码实现
#!/bin/bash
# 定义服务依赖关系,使用关联数组
declare -A dependencies=(
["serviceA"]="serviceB serviceC"
["serviceB"]="database"
)
# 启动服务函数
start_service() {
service_name=$1
if systemctl start $service_name; then
echo "$service_name 启动成功"
else
echo "$service_name 启动失败"
fi
}
# 停止服务函数
stop_service() {
service_name=$1
if systemctl stop $service_name; then
echo "$service_name 停止成功"
else
echo "$service_name 停止失败"
fi
}
# 检查服务是否运行函数
is_service_running() {
service_name=$1
if systemctl is-active --quiet $service_name; then
return 0
else
return 1
fi
}
# 按依赖顺序启动所有服务
start_all_services() {
for service in ${!dependencies[@]}; do
start_service $service
done
}
# 重启服务及其依赖服务
restart_service_and_dependencies() {
service_name=$1
local restart_count=0
local max_restart=3
local log_file="restart_log.log"
while (( restart_count < max_restart )); do
stop_service $service_name
for dependency in ${dependencies[$service_name]}; do
restart_service_and_dependencies $dependency
done
start_service $service_name
if is_service_running $service_name; then
echo "$service_name 重启成功"
return
else
((restart_count++))
echo "$service_name 重启失败,尝试第 $restart_count 次重启"
fi
done
echo "$service_name 多次重启失败,记录日志并通知管理员"
echo "$(date): $service_name 多次重启失败" >> $log_file
# 这里可以添加发送邮件通知管理员的代码,例如使用 mail 命令
# mail -s "服务重启失败" admin@example.com < $log_file
}
# 主监控循环
while true; do
for service in ${!dependencies[@]}; do
if! is_service_running $service; then
restart_service_and_dependencies $service
fi
done
sleep 5 # 每5秒检查一次服务状态
done
说明
- 关联数组
dependencies
:存储每个服务及其依赖关系。
start_service
和 stop_service
:使用 systemctl
命令启动和停止服务,并输出相应信息。
is_service_running
:使用 systemctl is - active
检查服务是否正在运行。
start_all_services
:按依赖顺序启动所有服务。
restart_service_and_dependencies
:递归重启服务及其依赖服务,并处理重启失败的情况。
- 主循环:不断检查每个服务的运行状态,发现停止的服务则调用重启函数。