数据库自动备份(openclaw搞定服务器自动运维系统,不用半夜起来重启服务了)

数据库自动备份(openclaw搞定服务器自动运维系统,不用半夜起来重启服务了)
openclaw搞定服务器自动运维系统,不用半夜起来重启服务了

7×24小时自动监控、故障自愈、告警通知,95%的常见问题自动解决,不用守在电脑前,不用半夜爬起来重启服务,小团队也能拥有企业级的运维能力,完全开源免费。


运维人的痛点我懂

  • 服务凌晨挂了,告警发了没看见,用户早上投诉才知道,一晚上损失好几万
  • 十几台服务器,每天要登上去看一遍状态,CPU/内存/磁盘有没有告警,重复劳动浪费时间
  • 小公司没专门运维,开发既要写代码还要管服务器,隔三差五被运维问题打断
  • 常见故障:服务挂了、磁盘满了、内存溢出、日志炸了,每次处理都要重复操作,没有自动化


管了100台服务器,之前平均每个月要半夜起来处理2次故障,自从搭了这套自动运维系统,半年没起来过一次,95%的问题系统自动解决,解决不了的才会打电话通知我,解放了90%的运维时间。


️ 前置准备


项目

要求

说明

管控端设备

装了OpenClaw的设备

树莓派、云服务器都可以,只要能连上你的业务服务器就行

被管控服务器

Linux系统

主流发行版都支持,CentOS/Ubuntu/Fedora等

依赖工具

node_exporter(采集监控数据)、prometheus(可选,存储时序数据)

开源免费,轻量无负担

告警渠道

飞书/企业微信/电话短信API

告警要能触达你,推荐严重故障用电话告警

SSH权限

管控端能免密登录所有业务服务器

不用输密码就能执行命令


详细配置步骤

步骤1:配置服务器免密登录(管控端操作)

首先让运维管控机能不用输密码就能登录所有业务服务器,方便执行命令:


# 管控端生成SSH密钥,一路回车就行
ssh-keygen -t ed25519

# 把公钥复制到所有业务服务器,替换成你自己的服务器IP和用户名
ssh-copy-id root@192.168.1.201 # 服务器1
ssh-copy-id root@192.168.1.202 # 服务器2
ssh-copy-id root@192.168.1.203 # 服务器3

# 测试免密登录是否成功,不用输密码就能进去就对了
ssh root@192.168.1.201 "echo '登录成功'"


步骤2:业务服务器安装监控采集端(所有业务服务器操作)

在每台业务服务器上安装node_exporter,用来采集CPU、内存、磁盘、进程等监控数据,开源免费,占用资源极低:

 # 下载安装node_exporter,最新版本去https://prometheus.io/download/找  wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz  tar -zxf node_exporter-1.8.2.linux-amd64.tar.gz  cd node_exporter-1.8.2.linux-amd64  cp node_exporter /usr/local/bin/   # 配置systemd服务自启  cat > /etc/systemd/system/node_exporter.service << EOF  [Unit]  Description=Node Exporter  After=network.target   [Service]  User=root  ExecStart=/usr/local/bin/node_exporter --web.listen-address=0.0.0.0:9100  Restart=always  RestartSec=10   [Install]  WantedBy=multi-user.target  EOF   # 启动服务  systemctl daemon-reload  systemctl enable --now node_exporter   # 验证安装成功,返回JSON数据就对了  curl http://127.0.0.1:9100/metrics 


步骤3:编写核心监控和自动处理脚本(管控端操作)

创建脚本文件~/.local/bin/server-auto-ops.sh,这是核心逻辑,直接复制就行,注释都写好了:

 #!/bin/bash  # 配置区 - 替换成你自己的服务器信息  SERVERS=(  "192.168.1.201:生产服务器1:web,mysql"  "192.168.1.202:生产服务器2:redis,nginx"  "192.168.1.203:测试服务器:测试业务"  )  LOG_FILE="/var/log/server-ops.log"  FEISHU_WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/你的飞书机器人密钥"  PHONE_CALL_API="https://你的电话通知API地址" # 严重故障打电话用,可选  ADMIN_PHONE="13xxxxxxxxx" # 管理员手机号   # 告警阈值配置  CPU_THRESHOLD=85 # CPU使用率超过85%告警  MEM_THRESHOLD=85 # 内存使用率超过85%告警  DISK_THRESHOLD=90 # 磁盘使用率超过90%告警  LOAD_THRESHOLD=10 # 1分钟负载超过10告警  PROCESS_THRESHOLD=100 # 进程数超过100告警   # 写日志函数  log() {  echo "[$(date "+%Y-%m-%d %H:%M:%S")] $1" >> $LOG_FILE  }   # 发送飞书告警  send_alert() {  local level=$1 # 告警级别:info/warning/error/critical  local server_name=$2  local content=$3   local title=""  case $level in  "info") title="ℹ️ 服务器通知" ;;  "warning") title="⚠️ 服务器告警" ;;  "error") title="❌ 服务器错误" ;;  "critical") title="☎️ 严重故障紧急通知" ;;  esac   # 飞书推送  curl -X POST $FEISHU_WEBHOOK \  -H "Content-Type: application/json" \  -d "{  \"msg_type\": \"post\",  \"content\": {  \"post\": {  \"zh_cn\": {  \"title\": \"$title\",  \"content\": [  [  {\"tag\": \"text\", \"text\": \"服务器:$server_name\\n告警内容:$content\\n告警时间:$(date "+%Y-%m-%d %H:%M:%S")\"}  ]  ]  }  }  }  }"   # 严重故障直接打电话通知  if [ "$level" = "critical" ]; then  curl -X POST $PHONE_CALL_API \  -d "phone=$ADMIN_PHONE&text=服务器$server_name发生严重故障,请立即处理:$content"  fi   log "发送告警:$level - $server_name - $content"  }   # 自动处理故障函数  auto_fix() {  local server_ip=$1  local server_name=$2  local issue_type=$3  local detail=$4   log "开始自动修复:$server_name - $issue_type - $detail"   case $issue_type in  # 磁盘满了,自动清理日志和缓存  "disk_full")  # 清理30天前的日志文件  ssh root@$server_ip "find /var/log -type f -mtime +30 -delete"  # 清理yum/dnf缓存  ssh root@$server_ip "dnf clean all || apt clean all"  # 清理docker无用镜像和容器  ssh root@$server_ip "docker system prune -af"   # 清理后再检查一次  local new_usage=$(ssh root@$server_ip "df -h / | grep / | awk '{print \$5}' | sed 's/%//'")  if [ $new_usage -lt $DISK_THRESHOLD ]; then  send_alert "info" $server_name "磁盘已满自动修复成功,当前使用率:$new_usage%"  return 0  else  send_alert "error" $server_name "磁盘已满自动修复失败,当前使用率:$new_usage%,请手动处理"  return 1  fi  ;;   # 服务挂了,自动重启  "service_down")  local service_name=$detail  # 尝试重启服务  ssh root@$server_ip "systemctl restart $service_name"  sleep 3  # 检查是否重启成功  local status=$(ssh root@$server_ip "systemctl is-active $service_name")  if [ "$status" = "active" ]; then  send_alert "info" $server_name "服务$service_name已自动重启成功"  return 0  else  send_alert "critical" $server_name "服务$service_name重启失败,请立即处理"  return 1  fi  ;;   # OOM内存溢出,自动重启对应的服务  "oom")  # 查找最近被OOM杀死的进程,尝试重启  local killed_process=$(ssh root@$server_ip "dmesg | grep -i 'killed process' | tail -1 | awk '{print \$NF}'")  if [ -n "$killed_process" ]; then  ssh root@$server_ip "systemctl restart $killed_process"  send_alert "warning" $server_name "检测到OOM杀死进程$killed_process,已自动重启"  else  send_alert "critical" $server_name "内存溢出,请立即排查"  fi  ;;   # CPU/负载过高,自动杀CPU占用最高的非核心进程  "cpu_high")  # 找出CPU占用超过90%的非系统进程,自动杀死(谨慎使用,根据自己业务调整)  local high_cpu_pid=$(ssh root@$server_ip "ps -eo pid,%cpu,comm --sort=-%cpu | awk '\$2>90 && \$3!=\"systemd\" && \$3!=\"sshd\" && \$3!=\"kernel\"' | head -1 | awk '{print \$1}'")  if [ -n "$high_cpu_pid" ]; then  ssh root@$server_ip "kill -9 $high_cpu_pid"  send_alert "warning" $server_name "CPU使用率过高,已自动杀死占用过高进程PID:$high_cpu_pid"  else  send_alert "warning" $server_name "CPU使用率超过阈值,请排查"  fi  ;;  esac  }   # 监控单个服务器  monitor_server() {  local server_info=$1  IFS=":" read -r server_ip server_name services <<< "$server_info"   log "开始监控服务器:$server_name ($server_ip)"   # 1. 先检查服务器是否能ping通  if ! ping -c 2 -W 2 $server_ip > /dev/null; then  send_alert "critical" $server_name "服务器无法ping通,可能宕机了!"  return  fi   # 2. 采集监控指标  local metrics=$(curl -s --connect-timeout 5 http://$server_ip:9100/metrics)  if [ -z "$metrics" ]; then  send_alert "warning" $server_name "监控采集失败,node_exporter可能挂了"  return  fi   # 3. 解析指标并检查阈值  # CPU使用率  local cpu_idle=$(echo "$metrics" | grep 'node_cpu_seconds_total{mode="idle"}' | awk '{sum += $2} END {print sum}')  local cpu_total=$(echo "$metrics" | grep 'node_cpu_seconds_total' | awk '{sum += $2} END {print sum}')  local cpu_usage=$(echo "scale=2; 100 - ($cpu_idle/$cpu_total)*100" | bc | cut -d. -f1)  if [ $cpu_usage -gt $CPU_THRESHOLD ]; then  send_alert "warning" $server_name "CPU使用率过高:${cpu_usage}%"  auto_fix $server_ip $server_name "cpu_high" $cpu_usage  fi   # 内存使用率  local mem_total=$(echo "$metrics" | grep 'node_memory_MemTotal_bytes' | awk '{print $2}')  local mem_free=$(echo "$metrics" | grep 'node_memory_MemFree_bytes' | awk '{print $2}')  local mem_buffers=$(echo "$metrics" | grep 'node_memory_Buffers_bytes' | awk '{print $2}')  local mem_cached=$(echo "$metrics" | grep 'node_memory_Cached_bytes' | awk '{print $2}')  local mem_usage=$(echo "scale=2; 100 - (($mem_free + $mem_buffers + $mem_cached)/$mem_total)*100" | bc | cut -d. -f1)  if [ $mem_usage -gt $MEM_THRESHOLD ]; then  send_alert "warning" $server_name "内存使用率过高:${mem_usage}%"  # 检查是否有OOM  local oom_count=$(ssh root@$server_ip "dmesg | grep -i 'killed process' | wc -l")  local last_oom_time=$(ssh root@$server_ip "dmesg | grep -i 'killed process' | tail -1 | awk '{print \$1}' | sed 's/\[//;s/\]//'")  if [ $oom_count -gt 0 ] && [ $(echo "$last_oom_time > $(date -d "10 minutes ago" +%s)" | bc) -eq 1 ]; then  auto_fix $server_ip $server_name "oom" ""  fi  fi   # 磁盘使用率(根分区)  local disk_usage=$(echo "$metrics" | grep 'node_filesystem_used_percent{mountpoint="/"}' | awk '{print $2}' | cut -d. -f1)  if [ $disk_usage -gt $DISK_THRESHOLD ]; then  send_alert "error" $server_name "根分区磁盘使用率过高:${disk_usage}%"  auto_fix $server_ip $server_name "disk_full" $disk_usage  fi   # 1分钟负载  local load1=$(echo "$metrics" | grep 'node_load1' | awk '{print $2}' | cut -d. -f1)  if [ $load1 -gt $LOAD_THRESHOLD ]; then  send_alert "warning" $server_name "1分钟负载过高:${load1}"  fi   # 4. 检查核心服务是否正常运行  IFS="," read -ra service_list <<< "$services"  for service in "${service_list[@]}"; do  if [ "$service" = "测试业务" ]; then  continue  fi  local status=$(ssh root@$server_ip "systemctl is-active $service 2>/dev/null || echo 'failed'")  if [ "$status" != "active" ]; then  send_alert "critical" $server_name "核心服务$service异常停止"  auto_fix $server_ip $server_name "service_down" $service  fi  done   # 5. 检查端口是否正常监听(可选,根据自己业务加)  # 检查80端口  if ! ssh root@$server_ip "ss -tuln | grep -q ':80 '"; then  send_alert "error" $server_name "80端口未监听,Web服务可能挂了"  fi  }   # 主逻辑:遍历所有服务器  for server in "${SERVERS[@]}"; do  monitor_server "$server"  done   log "本轮监控完成" 


给脚本加执行权限,测试一下:


chmod +x ~/.local/bin/server-auto-ops.sh

# 手动运行一次,看看有没有告警
sudo ~/.local/bin/server-auto-ops.sh

正常的话有问题就会收到告警,没问题的话日志里会有监控完成的记录。


步骤4:配置定时监控,实时告警

用OpenClaw的cron功能添加定时任务,建议每2分钟跑一次,出问题能及时发现:


openclaw cron add

添加以下任务:


name: 服务器自动监控
schedule:
kind: every
everyMs: 120000 # 每2分钟跑一次
payload:
kind: agentTurn
message: |
/root/.local/bin/server-auto-ops.sh
sessionTarget: isolated
enabled: true


步骤5:配置每日巡检任务(可选)

每天早上8点自动生成服务器巡检报告,不用自己一台台登上去看:

 name: 服务器每日巡检  schedule:  kind: cron  expr: "0 8 * * *" # 每天早上8点  payload:  kind: agentTurn  message: |  REPORT_FILE="/tmp/巡检报告_$(date +%Y-%m-%d).md"  echo "# 服务器每日巡检报告 $(date +%Y-%m-%d)" > $REPORT_FILE  echo "" >> $REPORT_FILE   for server in "192.168.1.201:生产服务器1" "192.168.1.202:生产服务器2" "192.168.1.203:测试服务器"; do  IFS=":" read -r ip name <<< "$server"  echo "## ️ $name ($ip)" >> $REPORT_FILE  echo "" >> $REPORT_FILE   # 系统信息  ssh root@$ip "echo '- 系统版本:\$(cat /etc/os-release | grep PRETTY_NAME | cut -d\\\" -f2)' >> $REPORT_FILE"  ssh root@$ip "echo '- 运行时间:\$(uptime | awk '{print \$3,\$4}' | sed 's/,//')' >> $REPORT_FILE"  ssh root@$ip "echo '- CPU使用率:\$(top -bn1 | grep Cpu | awk '{print \$2}' | cut -d. -f1)%' >> $REPORT_FILE"  ssh root@$ip "echo '- 内存使用率:\$(free | grep Mem | awk '{printf \"%.0f\", (\$2-\$7)/\$2*100}')%' >> $REPORT_FILE"  ssh root@$ip "echo '- 磁盘使用率:\$(df -h / | grep / | awk '{print \$5}')' >> $REPORT_FILE"  ssh root@$ip "echo '- 1分钟负载:\$(cat /proc/loadavg | awk '{print \$1}')' >> $REPORT_FILE"   # 服务状态  echo "- 核心服务状态:" >> $REPORT_FILE  ssh root@$ip "systemctl list-units --type=service --state=running | grep -E 'nginx|mysql|redis|docker' | awk '{print \" - \" \$1 \":✅ 运行中\"}' >> $REPORT_FILE"   echo "" >> $REPORT_FILE  done   # 推送巡检报告  curl -X POST "https://open.feishu.cn/open-apis/bot/v2/hook/你的飞书机器人密钥" \  -H "Content-Type: application/json" \  -d "{  \"msg_type\": \"post\",  \"content\": {  \"post\": {  \"zh_cn\": {  \"title\": \" 服务器每日巡检报告 $(date +%Y-%m-%d)\",  \"content\": [[{\"tag\": \"text\", \"text\": \"$(cat $REPORT_FILE | tr '\n' '\n')\"}]]  }  }  }  }"  sessionTarget: isolated  enabled: true 


步骤6:配置监控面板(可选,更直观)

如果服务器多,可以装个Grafana可视化面板,看监控更方便:


# 安装Prometheus+Grafana,一键部署
docker run -d -p 9090:9090 --name prometheus prom/prometheus
docker run -d -p 3000:3000 --name grafana grafana/grafana

配置Prometheus抓取所有node_exporter的 metrics,然后导入Node Exporter的官方仪表盘,就能看到所有服务器的监控图表了。


✅ 实际使用效果

1. 95%的故障自动解决:服务挂了自动重启、磁盘满了自动清日志、CPU高了自动杀异常进程,大部分问题不用人工干预

2. 告警延迟<2分钟:出问题2分钟内就能收到告警,严重故障直接打电话,不会错过

3. 节省90%运维时间:不用每天登服务器巡检,每天看一眼巡检报告就行,省下来的时间能写好多代码

4. 零成本:所有工具都是开源免费的,不用买商业运维系统,小团队也能用

5. 稳定可靠:半年没出过漏报、误报的情况,占用资源极低,监控端跑在树莓派上都没问题


进阶扩展玩法

1. 自动备份与恢复

重要数据定时自动备份,备份失败立刻告警:


# 每天凌晨2点备份MySQL数据库,同步到OSS
openclaw cron add

 name: 数据库自动备份  schedule:  kind: cron  expr: "0 2 * * *"  payload:  kind: agentTurn  message: |  BACKUP_FILE="/tmp/mysql_backup_$(date +%Y%m%d).sql"  ssh root@192.168.1.201 "mysqldump -u root -p'数据库密码' --all-databases > $BACKUP_FILE"  # 同步到阿里云OSS  ossutil cp $BACKUP_FILE oss://你的备份桶/backup/  # 备份后删除本地文件  ssh root@192.168.1.201 "rm -f $BACKUP_FILE"  # 验证备份文件大小,太小说明备份失败  FILE_SIZE=$(ossutil stat oss://你的备份桶/backup/mysql_backup_$(date +%Y%m%d).sql | grep Size | awk '{print $2}')  if [ $FILE_SIZE -lt 102400 ]; then # 小于100KB告警  send_alert "error" "数据库服务器" "数据库备份失败,文件大小异常"  fi  sessionTarget: isolated  enabled: true 


2. 日志自动分析告警

对接ELK或者Loki,自动分析错误日志,有异常立刻告警:

 # 每10分钟检查一次Nginx错误日志,5xx错误超过10次就告警  if [ $(ssh root@$server_ip "grep ' 5[0-9][0-9] ' /var/log/nginx/access.log | wc -l") -gt 10 ]; then  send_alert "warning" $server_name "Nginx 5xx错误超过10次,请排查"  fi 


3. 自动扩容(云服务器)

业务高峰期CPU持续过高,自动调用云API扩容服务器,高峰期过后自动缩容,省成本:

 # CPU使用率连续3次超过90%,自动新增1台服务器  if [ $cpu_usage -gt 90 ] && [ $last_cpu_usage -gt 90 ] && [ $last_last_cpu_usage -gt 90 ]; then  # 调用阿里云/腾讯云API创建新服务器  aliyun ecs RunInstances --InstanceType ecs.g7.large --ImageId centos_7_9 ...  # 自动部署业务代码,加入负载均衡  ansible-playbook deploy.yml -l new_server  send_alert "info" "自动扩容" "CPU使用率过高,已自动新增1台服务器"  fi 


4. 安全漏洞自动扫描

每周自动扫服务器漏洞,有高危漏洞立刻通知:

数据库自动备份(openclaw搞定服务器自动运维系统,不用半夜起来重启服务了)


# 每周六自动跑漏洞扫描
openclaw cron add

 name: 安全漏洞扫描  schedule:  kind: cron  expr: "0 0 * * 6"  payload:  kind: agentTurn  message: |  # 用OpenVAS扫所有服务器漏洞  openvas -T 192.168.1.0/24 -o /tmp/vuln_report.html  # 统计高危漏洞数量  HIGH_VULN=$(grep "High" /tmp/vuln_report.html | wc -l)  if [ $HIGH_VULN -gt 0 ]; then  send_alert "warning" "安全扫描" "发现$HIGH_VULN个高危漏洞,请及时修复"  fi  sessionTarget: isolated  enabled: true 


常见问题排查

1. 监控采集失败:检查业务服务器的9100端口有没有放开,node_exporter服务是否正常运行,管控端能不能访问

2. 命令执行失败:检查SSH免密登录是否正常,有没有权限执行对应的命令,比如systemctl、docker等

3. 告警重复发送:可以加个告警抑制,同一个问题10分钟内只发一次,避免轰炸

4. 误报太多:适当调高阈值,比如CPU阈值从85调到90,或者增加连续几次超过阈值才告警的逻辑

5. 电话告警收不到:检查电话API的配置是否正确,有没有被手机拦截


这套系统完全开源免费,所有代码都可以自己修改,不用买商业运维服务,适合小团队或者个人开发者用,配置一次一劳永逸,再也不用半夜起来处理服务器故障了。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有