MST

星途 面试题库

面试题:Bash脚本复杂自动化运维场景下的故障恢复

在一个复杂的自动化运维场景中,有多个服务依赖关系(例如:服务A依赖服务B和服务C,服务B依赖数据库服务)。编写一个Bash脚本,能够在系统启动时按顺序启动所有服务,并且在服务运行过程中,如果某个服务意外停止,脚本需要自动尝试重启该服务及其依赖的服务(如果必要)。同时,要考虑到在重启过程中可能出现的错误处理,例如多次重启失败后如何记录日志并通知管理员。请详细描述脚本的设计思路和关键代码实现。
44.2万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 服务依赖关系表示:使用一个数据结构(如关联数组)来存储每个服务及其依赖的服务。
  2. 启动顺序确定:根据依赖关系确定服务的启动顺序,先启动没有依赖的服务,再启动依赖这些服务的其他服务。
  3. 监控与重启:使用 while true 循环不断监控每个服务的运行状态,一旦发现服务停止,尝试重启该服务及其依赖的服务。
  4. 错误处理:记录重启失败的次数,达到一定次数后记录日志并通过邮件等方式通知管理员。

关键代码实现

#!/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

说明

  1. 关联数组 dependencies:存储每个服务及其依赖关系。
  2. start_servicestop_service:使用 systemctl 命令启动和停止服务,并输出相应信息。
  3. is_service_running:使用 systemctl is - active 检查服务是否正在运行。
  4. start_all_services:按依赖顺序启动所有服务。
  5. restart_service_and_dependencies:递归重启服务及其依赖服务,并处理重启失败的情况。
  6. 主循环:不断检查每个服务的运行状态,发现停止的服务则调用重启函数。