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

使用宝塔将项目定时同步到多台服务器(含 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 root@x.x.x.x // x.x.x.x为ip地址
    ssh-copy-id root@y.y.y.y // y.y.y.y为ip地址
  3. 验证免密登录是否成功:

    java 复制代码
    ssh root@x.x.x.x
    ssh root@y.y.y.y

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

• 方式:

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

bash 复制代码
#!/bin/bash

SRC="/www/wwwroot/your-main-project/"
DESTINATIONS=(
#192.168.1.10替换成你的ip地址 project-japan替换成你文件路径
  "root@192.168.1.10:/www/wwwroot/project-japan"  
  "root@192.168.1.20:/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 root@8.211.146.218  # 正常

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

相关推荐
GetcharZp1 分钟前
C++日志库新纪元:为什么说spdlog是现代C++开发者必备神器?
c++·后端
gnip3 分钟前
前端实现即时通讯,常用的技术
前端
三木水29 分钟前
Spring-rabbit使用实战七
java·分布式·后端·spring·消息队列·java-rabbitmq·java-activemq
烛阴36 分钟前
告别 any!用联合类型打造更灵活、更安全的 TS 代码
前端·typescript
快乐就是哈哈哈39 分钟前
一篇文章带你玩转 EasyExcel(Java Excel 报表必学)
后端
快乐就是哈哈哈40 分钟前
手把手教你用 Java 写出贪吃蛇小游戏(附源码)
后端
别来无恙1491 小时前
Spring Boot文件下载功能实现详解
java·spring boot·后端·数据导出
excel2 小时前
全面解析 JavaScript 类继承:方式、优缺点与应用场景
前端
用户21411832636022 小时前
dify案例分享-100% 识别率!发票、汇票、信用证全搞定的通用票据识别工作流
前端
公众号_醉鱼Java2 小时前
Elasticsearch文档数迷思:为何count和stats结果打架?深度解析背后机制
后端·掘金·金石计划