使用宝塔将项目定时同步到多台服务器(含 rsync 同步失败排查实战)
在我们项目上线部署过程中,遇到「一个主项目需要部署到多地服务器」的场景了。为了保持多台服务器文件的一致性,我选择使用 rsync
工具来实现文件同步,尤其结合 宝塔的计划任务功能,可以轻松实现 定时自动同步。
今天就分享一波我在实际操作中遇到的坑,以及解决过程,帮助大家少走弯路。
背景需求
- 项目 A 部署在一台主服务器(我们称为A服务器)
- 需要每天自动将该项目的文件同步到两台目标服务器(B和C)用于多地部署
- 使用宝塔面板设置定时任务,脚本通过
rsync
实现同步 - 同步失败后通过企业微信机器人发送告警
实现方案
使用宝塔面板 + 同步工具插件
rsync
+ 企业微信机器人,实现以下目标:
- 【源服务器】:定时同步文件目录到多台目标服务器
- 【目标服务器】:接收并替换相应文件
- 【同步方式】:
rsync
保留文件结构、增量同步 - 【异常告警】:企业微信群机器人即时通知
实施步骤详解
① 安装同步工具rsync
-
登录宝塔面板: 打开浏览器,访问宝塔面板的管理界面,输入用户名和密码登录。
-
进入终端: 在宝塔面板首页左侧菜单中,点击“终端”,进入命令行终端。
-
安装
rsync
: 在宝塔的终端中运行以下命令来安装rsync
:apt-get update apt-get install rsync
或者使用以下命令来安装
rsync
(如果你使用的是 CentOS 系统):yum install rsync
② 设置 SSH 免密登录
-
执行以下命令生成密钥(如已有可跳过):
ssh-keygen -t rsa
-
将公钥拷贝到目标服务器(B、C):
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地址
-
验证免密登录是否成功:
ssh root@x.x.x.x ssh root@y.y.y.y
③ 编写同步脚本(含告警功能)
• 方式:
在 /www/
目录新建脚本 sync-project.sh
,内容如下:
#!/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"
• 添加执行权限
chmod +x /www/sync-project.sh
④ 创建定时任务
-
打开宝塔面板 → 【计划任务】
-
点击【添加任务】
-
设置如下:
-
【任务类型】: Shell 脚本
-
【任务名称】: 定时同步项目文件
-
【执行周期】: 每小时执行一次 (可自定义)
-
【脚本内容】:
bash /www/sync-project.sh
-
-
点击【保存】
⑤ 目标服务器注意事项
确保同步的目标目录存在,并设置权限为:
chown -R www:www /www/wwwroot/project-japan
防止因权限问题导致 rsync: Permission denied 报错
⚠️ 效果展示(同步失败告警)
同步失败时,企业微信机器人会自动发送类似消息:
⚠️【同步失败】
目标服务器: x.x.x.x
失败时间: 2025-04-16 16:30:02
请尽快检查网络连接或 SSH 设置
总结
项目 | 工具方法 |
---|---|
自动同步 | 宝塔计划任务 + rsync |
多台部署 | DEST 列表自定义 |
告警机制 | 企业微信机器人 |
异常处理 | 日志记录 + 告警推送 |
实战问题
- 日志显示同步失败,企业微信收到告警
- 手动
ssh
到 B/C 服务器没问题 - 脚本执行中却总是卡在
rsync
阶段报错
排查过程
1. SSH 是能连的
bash
复制编辑
ssh root@8.211.146.218 # 正常
说明不是网络问题或 SSH key 问题。
2. 可能的错误原因
错误点 | 描述 |
---|---|
目标路径权限问题 | 例如目标目录是 www:www 所属,rsync 用 root 登录却无法写入 |
目录未创建 | rsync 无法自动创建多级目录,导致失败 |
防火墙、端口拦截 | 某些云服务器可能临时封锁了 22 端口 |
Host Key 检查提示 | 第一次连接会提示 ECDSA key fingerprint... ,脚本执行时阻塞卡住 |
rsync 未安装 | 目标服务器没有安装 rsync |
3. 最终发现的问题
通过下面命令确认:
ls -ld /www/wwwroot/xxx
发现目标路径是 www:www
所属,而 rsync
是用 root
登录去同步的。
🔧 解决方法:
chown -R root:root /www/wwwroot/xxx
chmod -R 755 /www/wwwroot/xxx
或,在 rsync
命令加上 --rsync-path="sudo rsync"
,前提是目标机 root 能 sudo。
✅ 最佳实践建议
- 首次连接先 ssh 一次,避免 fingerprint 阻塞
- 确保目录权限允许 root 写入
- 使用绝对路径,目录结尾加
/
,避免结构错乱 - 建议 rsync 添加
--rsync-path
或--chmod
参数更稳定 - 结合 WeCom 告警,问题实时掌握
- 目标服务器务必安装 rsync 工具!
🧾 结语
rsync
是文件同步中的瑞士军刀,但也不是“配置即飞”。尤其结合宝塔计划任务使用时,日志记录、权限预设、首次连接等细节一定要做好,不然临时同步失败就会出问题。