本文目录导读:

- 目录导读
- 为什么需要自动同步服务器文件?
- 主流同步工具对比:rsync vs scp vs 自定义脚本
- 方案一:基于rsync的增量同步脚本(推荐)
- 方案二:结合inotify实时触发同步脚本
- 方案三:多节点双向同步脚本(含冲突处理)
- 常见问答:同步脚本的坑与优化
- 总结与最佳实践
自动同步两台服务器文件的脚本实战指南
目录导读
- 为什么需要自动同步服务器文件?
- 主流同步工具对比:rsync vs scp vs 自定义脚本
- 基于rsync的增量同步脚本(推荐)
- 结合inotify实时触发同步脚本
- 多节点双向同步脚本(含冲突处理)
- 常见问答:同步脚本的坑与优化
- 总结与最佳实践
为什么需要自动同步服务器文件?
在日常运维中,我们常常面临以下场景:两台服务器分别承载Web应用的前后端,或者主备架构下需要保持配置文件、静态资源、数据库备份的一致性,手动复制文件不仅效率低下,还容易因遗漏导致环境差异,最终引发线上故障。自动同步脚本可以按计划(如cron)或事件触发(文件变更)执行操作,确保两台服务器数据实时或准实时一致。
痛点:单点故障、版本混乱、人工出错。解决方案:通过shell脚本或Python脚本,结合rsync、inotify等工具实现自动化。
主流同步工具对比:rsync vs scp vs 自定义脚本
| 工具/方案 | 特点 | 适用场景 |
|---|---|---|
| rsync | 增量传输、压缩、保留权限/时间戳、支持SSH隧道 | 大文件或整个目录的定期同步 |
| scp | 简单但每次全量传输,无增量能力 | 偶尔手动复制小文件 |
| 自定义脚本 | 可加入校验、日志、报警、冲突解决逻辑 | 需要灵活控制同步策略的环境 |
生产中90%的场景推荐rsync + 脚本,如果要求实时性则需配合inotify。
方案一:基于rsync的增量同步脚本(推荐)
1 脚本核心逻辑
- 通过ssh密钥免密登录
- 使用rsync的
-avz参数(归档模式+压缩) - 排除无需同步的目录(如.git, logs)
- 记录同步日志并邮件告警
2 完整Shell脚本示例
#!/bin/bash
# sync_to_backup.sh
# 用途:将主服务器 /data/web 同步到备份服务器 10.0.1.201:/data/web
SOURCE_DIR="/data/web"
DEST_SERVER="10.0.1.201"
DEST_DIR="/data/web"
LOG_FILE="/var/log/rsync-sync.log"
EXCLUDE_FILE="/etc/rsync_exclude.txt"
SSH_PORT=22
# 排除文件内容示例:*.log, node_modules, .git
# 发送通知函数
notify_admin() {
local subject="$1"
local body="$2"
echo "$body" | mail -s "$subject" admin@example.com
}
# 开始同步
echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始同步" >> "$LOG_FILE"
rsync -avz --delete --exclude-from="$EXCLUDE_FILE" -e "ssh -p $SSH_PORT -o StrictHostKeyChecking=no" \
"$SOURCE_DIR/" "$DEST_SERVER:$DEST_DIR" >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 同步成功" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') - 同步失败,请检查" >> "$LOG_FILE"
notify_admin "文件同步失败" "请登录主服务器查看 /var/log/rsync-sync.log"
fi
3 加入定时任务(cron)
# 每30分钟执行一次 */30 * * * * /usr/local/bin/sync_to_backup.sh
方案二:结合inotify实时触发同步脚本
rsync本身无法感知文件变更,需要定时轮询,如果要求秒级同步(如图片上传、配置文件修改),需借助inotify监听文件事件。
1 安装与依赖
# Ubuntu/Debian apt install inotify-tools -y # CentOS/RHEL yum install inotify-tools -y
2 实时同步脚本框架
#!/bin/bash
MONITOR_DIR="/data/web/uploads"
WATCH_EVENTS="modify,create,delete,move"
RSYNC_CMD="rsync -avz --delete $MONITOR_DIR/ 10.0.1.201:/data/web/uploads/"
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' \
-e "$WATCH_EVENTS" "$MONITOR_DIR" | while read datetime filepath event
do
echo "$datetime - 监听到 $filepath 发生 $event"
$RSYNC_CMD >> /var/log/inotify-rsync.log 2>&1
done
注意:inotify在文件大量变更时可能造成CPU高负载,建议配合rsync的--max-delete参数限制删除数量。
方案三:多节点双向同步脚本(含冲突处理)
当两台服务器都需要双向修改文件时(如共享配置文件),简单的从A到B同步将导致数据覆盖,此时需要最后一次修改为准或版本号合并策略。
1 核心思路
- 使用
rsync --update仅同步时间戳较新的文件 - 或者用unison工具实现双向同步
- 在脚本中加入
STATUS_FILE记录最后一次同步时间戳
2 简化版双向脚本(以较新文件为准)
#!/bin/bash
# 双向同步,先A到B,再B到A,覆盖规则:保留更新版本
SERVER_A="10.0.1.100"
SERVER_B="10.0.1.201"
SHARED_DIR="/data/shared"
LOG_DIR="/var/log/bidirectional_sync"
sync_direction() {
local from="$1"
local to="$2"
local from_dir="$3"
local to_dir="$4"
local label="$5"
rsync -avuz --delete -e "ssh -o StrictHostKeyChecking=no" \
"$from_dir/" "$to:$to_dir" > "$LOG_DIR/$label.log" 2>&1
}
# 先A同步到B
sync_direction "$SERVER_A" "$SERVER_B" "$SHARED_DIR" "$SHARED_DIR" "A_to_B"
# 再B同步到A
sync_direction "$SERVER_B" "$SERVER_A" "$SHARED_DIR" "$SHARED_DIR" "B_to_A"
注意:双向同步存在逻辑环风险,务必测试,建议只用于静态文件或做过版本控制的目录。
常见问答:同步脚本的坑与优化
Q1: 为什么rsync同步后文件权限变了?
A: 因为默认rsync不保留权限,需加-a(归档)参数,它包含-t(时间戳)、-r(递归)、-l(链接)、-p(权限)等,如果目标服务器用户不同,还需--chmod参数调整。
Q2: 如何处理网络突然中断导致的部分传输?
A: rsync天然支持断点续传,只要使用--partial参数(新版本默认启用),下次执行时会跳过已传输的部分,继续同步剩余内容。
Q3: 服务器数量超过2台怎么办?
A: 建议搭建中央同步节点(如使用lsyncd + rsync),或者引入分布式文件系统(如GlusterFS),对于3台以内,可扩展脚本为循环执行for循环。
Q4: 同步脚本如何安全保存密码/密钥?
A: 绝对不要在脚本中明文写入密码,正确做法:
- 使用ssh密钥对,并限制密钥用途(
command=或from=限制IP) - 或者使用ansible vault加密敏感变量
Q5: 如何监控同步是否正常?
A: 在脚本中添加:
- 输出到日志并监控日志文件最后修改时间(通过zabbix或prometheus)
- 同步成功后写入心跳文件(如
touch /tmp/sync_ok) - 发送告警到钉钉/企业微信webhook
总结与最佳实践
自动同步两台服务器文件的脚本是运维标准化的重要手段,结合上文,我建议:
- 优先选择rsync + cron(非实时场景),稳定且资源消耗低。
- 实时场景用inotify + rsync,但注意监控资源,可限速
--bwlimit。 - 双向同步慎用,务必加上
--dry-run测试,并做好版本备份。 - 日志与告警不可少,否则同步失败可能导致长时间数据不一致。
- 定期测试恢复流程,同步脚本本身也应纳入版本管理。
推荐将脚本托管在GitLab/GitHub私有仓库,并使用chmod +x赋予执行权限,配合cron或systemd timer实现无人值守。
延伸阅读:如有需要可参考官方文档,域名示例:rsync官网(rsync.samba.org)和inotify手册(linux.die.net/man/1/inotifywait)。