前端实现多服务器文件 自动同步宝塔定时任务 + 同步工具 + 企业微信告警(实战详解)

使用宝塔将项目定时同步到多台服务器(含 rsync 同步失败排查实战)

在我们项目上线部署过程中,遇到「一个主项目需要部署到多地服务器 」的场景了。为了保持多台服务器文件的一致性,我选择使用 rsync 工具来实现文件同步,尤其结合 宝塔的计划任务功能 ,可以轻松实现 定时自动同步

今天就分享一波我在实际操作中遇到的坑,以及解决过程,帮助大家少走弯路。


🧩 背景需求

  • 项目 A 部署在一台主服务器(我们称为A服务器)
  • 需要每天自动将该项目的文件同步到两台目标服务器(B和C)用于多地部署
  • 使用宝塔面板设置定时任务,脚本通过 rsync 实现同步
  • 同步失败后通过企业微信机器人发送告警

🏆 实现方案

使用宝塔面板 + 同步工具插件 rsync + 企业微信机器人,实现以下目标:

  • 【源服务器】:定时同步文件目录到多台目标服务器
  • 【目标服务器】:接收并替换相应文件
  • 【同步方式】:rsync 保留文件结构、增量同步
  • 【异常告警】:企业微信群机器人即时通知

🛠️ 实施步骤详解

① 安装同步工具rsync

  1. 登录宝塔面板: 打开浏览器,访问宝塔面板的管理界面,输入用户名和密码登录。

  2. 进入终端: 在宝塔面板首页左侧菜单中,点击"终端",进入命令行终端。

  3. 安装 rsync : 在宝塔的终端中运行以下命令来安装 rsync

    sql 复制代码
    apt-get update
    apt-get install rsync

    或者使用以下命令来安装 rsync(如果你使用的是 CentOS 系统):

    复制代码
    yum install rsync

② 设置 SSH 免密登录

  1. 执行以下命令生成密钥(如已有可跳过):

    复制代码
    ssh-keygen -t rsa
  2. 将公钥拷贝到目标服务器(B、C):

    go 复制代码
    ssh-copy-id [email protected] // x.x.x.x为ip地址
    ssh-copy-id [email protected] // y.y.y.y为ip地址
  3. 验证免密登录是否成功:

    java 复制代码
    ssh [email protected]
    ssh [email protected]

③ 编写同步脚本(含告警功能)

• 方式:

/www/ 目录新建脚本 sync-project.sh,内容如下:

bash 复制代码
#!/bin/bash

SRC="/www/wwwroot/your-main-project/"
DESTINATIONS=(
#192.168.1.10替换成你的ip地址 project-japan替换成你文件路径
  "[email protected]:/www/wwwroot/project-japan"  
  "[email protected]:/www/wwwroot/project-russia"
)

LOG_FILE="/www/sync-log.txt"
WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx" //xxx为你企微机器人的key
TIME=$(date "+%Y-%m-%d %H:%M:%S")

send_wechat_alert() {
  local dest_ip=$1
  local msg="⚠️【同步失败】\n目标服务器: $dest_ip\n失败时间: $TIME\n请尽快检查网络连接或 SSH 设置"

  curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "{
      "msgtype": "text",
      "text": {
        "content": "$msg"
      }
    }" > /dev/null
}

echo "------------------------------------------------" >> "$LOG_FILE"
echo "[$TIME] 🔄 开始同步任务" >> "$LOG_FILE"

for DEST in "${DESTINATIONS[@]}"; do
  IP=$(echo "$DEST" | cut -d@ -f2 | cut -d: -f1)
  echo "[$TIME] ▶️ 正在同步到 $IP ..." >> "$LOG_FILE"

  rsync -azP --delete "$SRC" "$DEST"
  if [ $? -eq 0 ]; then
    echo "[$TIME] ✅ 同步到 $IP 成功" >> "$LOG_FILE"
  else
    echo "[$TIME] ❌ 同步到 $IP 失败" >> "$LOG_FILE"
    send_wechat_alert "$IP"
  fi

done

echo "[$TIME] 🏁 同步任务结束" >> "$LOG_FILE"
• 添加执行权限
bash 复制代码
chmod +x /www/sync-project.sh

④ 创建定时任务

  1. 打开宝塔面板 → 【计划任务】

  2. 点击【添加任务】

  3. 设置如下:

    • 【任务类型】: Shell 脚本

    • 【任务名称】: 定时同步项目文件

    • 【执行周期】: 每小时执行一次 (可自定义)

    • 【脚本内容】:

      bash 复制代码
      bash /www/sync-project.sh
  4. 点击【保存】


⑤ 目标服务器注意事项

确保同步的目标目录存在,并设置权限为:

bash 复制代码
chown -R www:www /www/wwwroot/project-japan

防止因权限问题导致 rsync: Permission denied 报错


⚠️ 效果展示(同步失败告警)

同步失败时,企业微信机器人会自动发送类似消息:

makefile 复制代码
⚠️【同步失败】
目标服务器: x.x.x.x
失败时间: 2025-04-16 16:30:02
请尽快检查网络连接或 SSH 设置

✅ 总结

项目 工具方法
自动同步 宝塔计划任务 + rsync
多台部署 DEST 列表自定义
告警机制 企业微信机器人
异常处理 日志记录 + 告警推送

🚨 实战问题

  • 日志显示同步失败,企业微信收到告警
  • 手动 ssh 到 B/C 服务器没问题
  • 脚本执行中却总是卡在 rsync 阶段报错

🔍 排查过程

✅ 1. SSH 是能连的

perl 复制代码
bash
复制编辑
ssh [email protected]  # 正常

说明不是网络问题或 SSH key 问题。


🛑 2. 可能的错误原因

错误点 描述
目标路径权限问题 例如目标目录是 www:www 所属,rsync 用 root 登录却无法写入
目录未创建 rsync 无法自动创建多级目录,导致失败
防火墙、端口拦截 某些云服务器可能临时封锁了 22 端口
Host Key 检查提示 第一次连接会提示 ECDSA key fingerprint...,脚本执行时阻塞卡住
rsync 未安装 目标服务器没有安装 rsync

✅ 3. 最终发现的问题

通过下面命令确认:

bash 复制代码
ls -ld /www/wwwroot/xxx

发现目标路径是 www:www 所属,而 rsync 是用 root 登录去同步的。

🔧 解决方法

bash 复制代码
chown -R root:root /www/wwwroot/xxx
chmod -R 755 /www/wwwroot/xxx

或,在 rsync 命令加上 --rsync-path="sudo rsync",前提是目标机 root 能 sudo。


✅ 最佳实践建议

  1. 首次连接先 ssh 一次,避免 fingerprint 阻塞
  2. 确保目录权限允许 root 写入
  3. 使用绝对路径,目录结尾加 /,避免结构错乱
  4. 建议 rsync 添加 --rsync-path--chmod 参数更稳定
  5. 结合 WeCom 告警,问题实时掌握
  6. 目标服务器务必安装 rsync 工具!

🧾 结语

rsync 是文件同步中的瑞士军刀,但也不是"配置即飞"。尤其结合宝塔计划任务使用时,日志记录、权限预设、首次连接等细节一定要做好,不然临时同步失败就会出问题。

相关推荐
why1516 分钟前
微服务商城-商品微服务
数据库·后端·golang
crary,记忆1 小时前
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
前端·webpack·angular·angular.js
漂流瓶jz2 小时前
让数据"流动"起来!Node.js实现流式渲染/流式传输与背后的HTTP原理
前端·javascript·node.js
SamHou02 小时前
手把手 CSS 盒子模型——从零开始的奶奶级 Web 开发教程2
前端·css·web
我不吃饼干2 小时前
从 Vue3 源码中了解你所不知道的 never
前端·typescript
結城2 小时前
mybatisX的使用,简化springboot的开发,不用再写entity、mapper以及service了!
java·spring boot·后端
开航母的李大2 小时前
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
前端·redis·nginx·缓存·微服务·kafka
Bruk.Liu2 小时前
《Minio 分片上传实现(基于Spring Boot)》
前端·spring boot·minio
星辰离彬3 小时前
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
java·spring boot·后端·sql·mysql·性能优化
鱼樱前端3 小时前
Vue3+d3-cloud+d3-scale+d3-scale-chromatic实现词云组件
前端·javascript·vue.js