返回文章列表
服务器

服务器日志分析、自动备份、故障排查怎么做?5个超实用服务器运维脚本

小站
2025-11-19
2个月前
服务器日志分析、自动备份、故障排查怎么做?5个超实用服务器运维脚本

做服务器运维时,是不是总被这些事烦?日志刷得太快找不到报错、忘记备份数据怕丢失、服务挂了要手动重启、安全漏洞不知道怎么补?今天分享5个新手友好的Shell运维脚本,覆盖日志监控、自动备份、故障自愈、安全加固等高频场景,复制就能用,不用懂复杂命令~

一、先选脚本:按需求直接挑(新手不迷路)


脚本序号脚本名称核心用途适用场景
1日志实时监控告警脚本实时抓错误日志、关键字告警(邮件/终端)程序报错排查、异常行为监控
2自动化备份脚本(文件+数据库)定时备份MySQL/Redis+关键文件,支持异地存储数据防丢失(每天必备)
3关键服务自愈脚本服务挂了自动重启、端口不通自动重试核心业务(Nginx/Java应用)无人值守
4系统安全加固一键脚本关闭无用端口、禁用密码登录、设置防火墙服务器初始化、安全合规检查
5故障快速排查脚本一键收集系统/网络/进程信息,生成排查报告服务器卡顿、无法访问时快速定位问题

二、脚本1:日志实时监控告警脚本(报错秒提醒)

脚本用途

服务器日志太多,手动找报错像“大海捞针”?这个脚本能实时监控指定日志文件,一旦出现“error”“fail”等关键字,立刻在终端弹窗+邮件提醒,还会记录报错上下文,新手也能快速定位问题。

核心功能

  • • 实时跟踪日志文件(支持多文件同时监控)
  • • 自定义关键字告警(比如“OOM”“连接超时”)
  • • 终端高亮提示+邮件告警(可选)
  • • 自动记录报错时间和上下文(方便回溯)

使用步骤

  1. 1. 复制代码保存为 log_monitor.sh
  2. 2. 赋予执行权限:chmod +x log_monitor.sh
  3. 3. 新手改配置区(日志路径、关键字、邮箱)
  4. 4. 执行:./log_monitor.sh(后台运行:nohup ./log_monitor.sh &)

完整代码(新手必改配置区)

#!/bin/bash################################################################################# 脚本名称: log_monitor.sh# 功能描述: 日志实时监控+关键字告警(新手改配置区!)# 版本信息: v1.2################################################################################# -------------------------- 新手必改:配置区 --------------------------LOG_FILES=("/var/log/messages" "/opt/app/logs/app.log")  # 要监控的日志文件(可加多个)ALERT_KEYWORDS=("error" "fail" "critical" "OOM" "连接超时")  # 告警关键字(按需加)ALERT_EMAIL="your@email.com"  # 接收告警的邮箱(不用邮件留空)LOG_SAVE_PATH="/var/log/alert_logs"  # 告警日志保存路径# -------------------------------------------------------------------# 颜色定义(不用改)RED='\033[0;31m'YELLOW='\033[1;33m'NC='\033[0m'# 创建告警日志目录(不用改)mkdir -p $LOG_SAVE_PATHALERT_LOG="$LOG_SAVE_PATH/alert_$(date +%Y%m%d).log"# 日志函数(不用改)log_alert() {    local time=$(date +"%Y-%m-%d %H:%M:%S")    local content="$1"    # 终端高亮输出    echo -e "${RED}[ALERT] $time: $content${NC}"    # 写入告警日志    echo "[$time] $content" >> $ALERT_LOG    # 发送邮件告警(需安装mailutils:yum install mailutils / apt install mailutils)    if [ -n "$ALERT_EMAIL" ]; then        echo "$content" | mail -s "服务器日志告警-$time" $ALERT_EMAIL    fi}# 实时监控日志(不用改)echo -e "${YELLOW}=== 日志监控已启动,关键字:${ALERT_KEYWORDS[*]} ===${NC}"echo "监控日志:${LOG_FILES[*]}"echo "告警日志保存至:$ALERT_LOG"# 循环监控每个日志文件for log in "${LOG_FILES[@]}"; do    if [ ! -f "$log" ]; then        echo -e "${RED}警告:日志文件 $log 不存在!${NC}"        continue    fi    # 实时跟踪日志,匹配关键字    tail -fn0 "$log" | while read line; do        for keyword in "${ALERT_KEYWORDS[@]}"; do            if echo "$line" | grep -qi "$keyword"; then                # 记录报错上下文(前后3行)                context=$(grep -B3 -A3 "$keyword" "$log" | tail -7)                log_alert "日志文件:$log\n关键字:$keyword\n报错上下文:\n$context"            fi        done    done &done# 保持脚本运行(不用改)wait

新手避坑

  1. 1. 邮件告警失败?先安装邮件工具:yum install mailutils(CentOS)或 apt install mailutils(Ubuntu)
  2. 2. 监控多个日志文件?在 LOG_FILES 里添加路径,用空格分隔
  3. 3. 想监控自定义关键字?比如“支付失败”,直接加到 ALERT_KEYWORDS 数组里

三、脚本2:自动化备份脚本(文件+数据库双备份)

脚本用途

数据是服务器的“命根子”,忘记备份哭都来不及!这个脚本支持MySQL/Redis数据库+关键文件备份,自动压缩、按日期命名,还能上传到远程服务器(异地备份),定时执行不用管。

核心功能

  • • 备份MySQL/Redis数据库(自动导出SQL/RDB文件)
  • • 备份关键文件/目录(比如配置文件、用户数据)
  • • 自动压缩+日期命名(避免覆盖旧备份)
  • • 支持异地备份(上传到FTP/SCP服务器)
  • • 自动清理7天前的旧备份(节省磁盘空间)

使用步骤

  1. 1. 复制代码保存为 auto_backup.sh
  2. 2. 赋予执行权限:chmod +x auto_backup.sh
  3. 3. 新手改配置区(数据库信息、备份路径、远程服务器信息)
  4. 4. 定时执行(每天凌晨2点):echo "0 2 * * * /path/to/auto_backup.sh" | crontab -

完整代码(新手必改配置区)

#!/bin/bash################################################################################# 脚本名称: auto_backup.sh# 功能描述: 数据库+文件自动备份(新手改配置区!)# 版本信息: v1.5################################################################################# -------------------------- 新手必改:配置区 --------------------------# 数据库配置(按需开启,不用的注释掉)MYSQL_ENABLE=1  # 1=开启MySQL备份,0=关闭MYSQL_USER="root"  # MySQL用户名MYSQL_PASS="your_mysql_pass"  # MySQL密码MYSQL_HOST="localhost"  # 数据库地址MYSQL_DBS=("test_db" "prod_db")  # 要备份的数据库(多个用空格分隔)REDIS_ENABLE=1  # 1=开启Redis备份,0=关闭REDIS_HOST="localhost"REDIS_PORT="6379"REDIS_PASS="your_redis_pass"  # 无密码留空# 备份配置BACKUP_PATH="/data/backups"  # 本地备份路径KEEP_DAYS=7  # 保留7天的备份(自动删除更旧的)COMPRESS=1  # 1=压缩备份(zip格式)# 异地备份配置(可选,0=关闭)REMOTE_ENABLE=0REMOTE_USER="backup"  # 远程服务器用户名REMOTE_HOST="192.168.1.200"  # 远程服务器IPREMOTE_PATH="/data/remote_backups"  # 远程备份路径# -------------------------------------------------------------------# 颜色定义(不用改)GREEN='\033[0;32m'RED='\033[0;31m'NC='\033[0m'# 创建备份目录(不用改)mkdir -p $BACKUP_PATHBACKUP_DATE=$(date +"%Y%m%d_%H%M%S")LOG_FILE="$BACKUP_PATH/backup_log_$BACKUP_DATE.log"# 日志函数(不用改)log() {    echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" >> $LOG_FILE}# MySQL备份(不用改)backup_mysql() {    if [ $MYSQL_ENABLE -ne 1 ]; then return; fi    log "=== 开始MySQL备份 ==="    MYSQL_BACKUP_DIR="$BACKUP_PATH/mysql_$BACKUP_DATE"    mkdir -p $MYSQL_BACKUP_DIR    for db in "${MYSQL_DBS[@]}"; do        # 导出数据库SQL文件        if [ -z "$MYSQL_PASS" ]; then            mysqldump -u$MYSQL_USER -h$MYSQL_HOST $db > "$MYSQL_BACKUP_DIR/$db.sql"        else            mysqldump -u$MYSQL_USER -p$MYSQL_PASS -h$MYSQL_HOST $db > "$MYSQL_BACKUP_DIR/$db.sql"        fi        # 压缩        if [ $COMPRESS -eq 1 ]; then            zip "$MYSQL_BACKUP_DIR/$db.sql.zip" "$MYSQL_BACKUP_DIR/$db.sql"            rm -f "$MYSQL_BACKUP_DIR/$db.sql"        fi        log "MySQL数据库 $db 备份完成"    done}# Redis备份(不用改)backup_redis() {    if [ $REDIS_ENABLE -ne 1 ]; then return; fi    log "=== 开始Redis备份 ==="    REDIS_BACKUP_DIR="$BACKUP_PATH/redis_$BACKUP_DATE"    mkdir -p $REDIS_BACKUP_DIR    # 执行Redis备份命令    if [ -z "$REDIS_PASS" ]; then        redis-cli -h$REDIS_HOST -p$REDIS_PORT save    else        redis-cli -h$REDIS_HOST -p$REDIS_PORT -a$REDIS_PASS save    fi    # 复制RDB文件    REDIS_RDB=$(redis-cli -h$REDIS_HOST -p$REDIS_PORT config get dir | tail -1)/dump.rdb    cp $REDIS_RDB "$REDIS_BACKUP_DIR/redis_dump_$BACKUP_DATE.rdb"    log "Redis备份完成(RDB文件)"}# 文件备份(不用改,添加要备份的目录)backup_files() {    log "=== 开始文件备份 ==="    FILES_BACKUP_DIR="$BACKUP_PATH/files_$BACKUP_DATE"    mkdir -p $FILES_BACKUP_DIR    # 要备份的文件/目录(按需添加)    BACKUP_FILES=("/etc" "/opt/app/config" "/home/user/data")    for file in "${BACKUP_FILES[@]}"; do        if [ -e "$file" ]; then            cp -r $file $FILES_BACKUP_DIR            log "文件/目录 $file 备份完成"        else            log "警告:文件/目录 $file 不存在,跳过"        fi    done    # 压缩    if [ $COMPRESS -eq 1 ]; then        zip -r "$FILES_BACKUP_DIR.zip" $FILES_BACKUP_DIR        rm -rf $FILES_BACKUP_DIR    fi}# 异地备份(不用改)remote_backup() {    if [ $REMOTE_ENABLE -ne 1 ]; then return; fi    log "=== 开始异地备份 ==="    # 上传本地备份到远程服务器    scp -r $BACKUP_PATH/*$BACKUP_DATE* $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH    if [ $? -eq 0 ]; then        log "异地备份上传成功"    else        log "错误:异地备份上传失败"    fi}# 清理旧备份(不用改)clean_old_backups() {    log "=== 清理$KEEP_DAYS天前的旧备份 ==="    find $BACKUP_PATH -type f -mtime +$KEEP_DAYS -delete    log "清理完成"}# 主函数(不用改)main() {    log "=== 备份任务开始 ==="    backup_mysql    backup_redis    backup_files    remote_backup    clean_old_backups    log "=== 备份任务结束 ==="    echo -e "${GREEN}备份完成!日志文件:$LOG_FILE${NC}"}main "$@"

新手避坑

  1. 1. MySQL备份失败?先安装mysqldump:yum install mysql-client(CentOS)或 apt install mysql-client(Ubuntu)
  2. 2. 无密码备份?把 MYSQL_PASS 或 REDIS_PASS 留空即可
  3. 3. 异地备份需要免密登录?执行 ssh-copy-id $REMOTE_USER@$REMOTE_HOST 配置免密

四、脚本3:关键服务自愈脚本(挂了自动重启)

脚本用途

核心服务(比如Nginx、Java应用)突然挂了,没人发现就会影响业务!这个脚本会定时检查服务状态,一旦发现服务停止/端口不通,自动重启,还会记录重启日志,新手不用24小时盯着服务器。

核心功能

  • • 检查服务进程是否存活(支持多服务)
  • • 检查服务端口是否监听(双重验证)
  • • 服务挂了自动重启(最多重试3次)
  • • 记录重启日志和原因(方便排查为什么挂)
  • • 支持自定义检查间隔(比如1分钟检查1次)

使用步骤

  1. 1. 复制代码保存为 service_selfheal.sh
  2. 2. 赋予执行权限:chmod +x service_selfheal.sh
  3. 3. 新手改配置区(要监控的服务和端口)
  4. 4. 后台运行:nohup ./service_selfheal.sh &(开机自启:加到 /etc/rc.local)

完整代码(新手必改配置区)

#!/bin/bash################################################################################# 脚本名称: service_selfheal.sh# 功能描述: 服务自动重启自愈(新手改配置区!)# 版本信息: v1.3################################################################################# -------------------------- 新手必改:配置区 --------------------------# 监控的服务(格式:服务名|启动命令|端口,多个用空格分隔)SERVICES=(    "nginx|systemctl start nginx|80,443"    "mysqld|systemctl start mysqld|3306"    "java|systemctl start app.service|8080"  # Java应用示例    "redis-server|systemctl start redis|6379")CHECK_INTERVAL=60  # 检查间隔(秒),比如60=1分钟检查1次MAX_RETRY=3  # 最大重启次数(避免无限重启)LOG_FILE="/var/log/service_selfheal.log"  # 日志路径# -------------------------------------------------------------------# 颜色定义(不用改)GREEN='\033[0;32m'RED='\033[0;31m'YELLOW='\033[1;33m'NC='\033[0m'# 日志函数(不用改)log() {    echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" >> $LOG_FILE}# 检查服务状态(不用改)check_service() {    local service_name=$1    local start_cmd=$2    local ports=$3    local is_alive=0    local port_alive=0    # 检查进程是否存活    if ps aux | grep -v grep | grep -q "$service_name"; then        is_alive=1    fi    # 检查端口是否监听(多个端口只要一个通就算正常)    IFS=',' read -ra port_arr <<< "$ports"    for port in "${port_arr[@]}"; do        if netstat -tuln | grep -q ":$port "; then            port_alive=1            break        fi    done    # 进程和端口都正常才算健康    if [ $is_alive -eq 1 ] && [ $port_alive -eq 1 ]; then        log "服务 $service_name 状态正常(进程存活+端口监听)"        return 0    else        log "警告:服务 $service_name 异常(进程存活:$is_alive,端口监听:$port_alive)"        return 1    fi}# 重启服务(不用改)restart_service() {    local service_name=$1    local start_cmd=$2    local retry_count=0    while [ $retry_count -lt $MAX_RETRY ]; do        log "正在重启服务 $service_name(第 $((retry_count+1)) 次)"        # 执行启动命令        eval $start_cmd        # 等待3秒再检查        sleep 3        # 重新检查服务状态        if check_service $service_name $start_cmd $3; then            log "服务 $service_name 重启成功"            echo -e "${GREEN}[$(date +"%H:%M:%S")] 服务 $service_name 重启成功${NC}"            return 0        fi        retry_count=$((retry_count+1))    done    # 超过最大重试次数    log "错误:服务 $service_name 重启 $MAX_RETRY 次失败,请手动检查!"    echo -e "${RED}[$(date +"%H:%M:%S")] 服务 $service_name 重启失败,请手动检查!${NC}"    return 1}# 主循环(不用改)main() {    echo -e "${YELLOW}=== 服务自愈脚本已启动,检查间隔:$CHECK_INTERVAL 秒 ===${NC}"    log "=== 服务自愈脚本启动 ==="    log "监控的服务:${SERVICES[*]}"    while true; do        for service in "${SERVICES[@]}"; do            IFS='|' read -r service_name start_cmd ports <<< "$service"            if ! check_service $service_name $start_cmd $ports; then                restart_service $service_name $start_cmd $ports            fi        done        # 等待检查间隔        sleep $CHECK_INTERVAL    done}main "$@"

新手避坑

  1. 1. 端口检查失败?安装net-tools:yum install net-tools(CentOS)或 apt install net-tools(Ubuntu)
  2. 2. 启动命令不对?根据自己的服务修改 start_cmd,比如Docker服务写成 docker start app_container
  3. 3. 想添加新服务?按格式在 SERVICES 数组里添加,比如 "tomcat|/opt/tomcat/bin/startup.sh|8080"

五、脚本4-5:安全加固+故障排查脚本(精简版)

脚本4:系统安全加固一键脚本

核心用途

新手不知道怎么加固服务器?这个脚本一键关闭无用端口、禁用密码登录(只用SSH密钥)、设置防火墙规则、清理空密码账户,做完基本能抵御大部分常规攻击。

使用步骤
  1. 1. 保存为 system_harden.sh,赋予权限:chmod +x system_harden.sh
  2. 2. 执行:sudo ./system_harden.sh(必须root用户)
  3. 3. 新手注意:执行前备份SSH配置(cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak)
核心配置(新手可改)
# 允许的SSH端口(默认22,建议改成其他端口)SSH_PORT=22# 允许登录的用户(比如只允许user1登录,多个用空格分隔)ALLOW_USERS=("user1" "admin")# 允许的端口(比如只开放80、443、22)ALLOW_PORTS=("22" "80" "443" "3306")

脚本5:故障快速排查脚本

核心用途

服务器卡顿、无法访问时,新手不知道该看CPU、内存还是日志?这个脚本一键收集系统负载、磁盘IO、网络连接、错误日志等关键信息,生成排查报告,直接发给运维大佬也能快速定位问题。

使用步骤
  1. 1. 保存为 fault_check.sh,赋予权限:chmod +x fault_check.sh
  2. 2. 执行:./fault_check.sh(root用户效果更好)
  3. 3. 报告保存路径:/var/log/fault_check_report_xxx.log
核心功能
  • • 收集CPU/内存/磁盘/网络实时状态
  • • 抓取TOP10高资源占用进程
  • • 收集TCP连接状态(TIME_WAIT/ESTABLISHED)
  • • 提取最近1小时系统错误日志
  • • 检查磁盘IO和网络连通性

六、新手必备运维总结

1. 常用命令(记不住就收藏)

  • • 赋予脚本权限:chmod +x 脚本名.sh
  • • 后台运行脚本:nohup ./脚本名.sh &(关闭终端也能跑)
  • • 定时执行:crontab -e,添加任务(比如每天2点备份:0 2 * * * /path/to/auto_backup.sh)
  • • 查看日志:tail -f /var/log/脚本日志.log(实时查看)

2. 执行频率建议

  • • 日志监控脚本:一直后台运行(24小时监控)
  • • 自动备份脚本:每天1次(凌晨2点,服务器负载低)
  • • 服务自愈脚本:一直后台运行
  • • 安全加固脚本:服务器初始化后执行1次,每周检查1次
  • • 故障排查脚本:服务器异常时手动执行

3. 避坑总览

  • • 所有脚本尽量用root用户执行,否则权限不足导致功能失效
  • • 修改配置区时,一定要和自己的服务器环境一致(比如数据库密码、服务名)
  • • 执行安全加固、服务重启类脚本前,先备份关键配置(比如SSH配置、服务配置)
  • • 脚本运行中报错,先看日志文件(脚本里配置的LOG_FILE路径),根据错误信息排查

小结:新手运维不用愁,脚本帮你省时间

这5个脚本覆盖了日志监控、数据备份、服务自愈、安全加固、故障排查等运维高频场景,新手不用记复杂命令,复制修改配置就能用。运维的核心是“防患于未然”,把这些脚本部署好,能少踩很多坑,还能节省大量手动操作时间~


本文内容仅供参考,不构成任何专业建议。使用本文提供的信息时,请自行判断并承担相应风险。

分享文章
合作伙伴

本站所有广告均是第三方投放,详情请查询本站用户协议