自动同步两台服务器文件的脚本

wen 实用脚本 1

本文目录导读:

自动同步两台服务器文件的脚本

  1. 目录导读
  2. 为什么需要自动同步服务器文件?
  3. 主流同步工具对比:rsync vs scp vs 自定义脚本
  4. 方案一:基于rsync的增量同步脚本(推荐)
  5. 方案二:结合inotify实时触发同步脚本
  6. 方案三:多节点双向同步脚本(含冲突处理)
  7. 常见问答:同步脚本的坑与优化
  8. 总结与最佳实践

自动同步两台服务器文件的脚本实战指南

目录导读

  1. 为什么需要自动同步服务器文件?
  2. 主流同步工具对比:rsync vs scp vs 自定义脚本
  3. 基于rsync的增量同步脚本(推荐)
  4. 结合inotify实时触发同步脚本
  5. 多节点双向同步脚本(含冲突处理)
  6. 常见问答:同步脚本的坑与优化
  7. 总结与最佳实践

为什么需要自动同步服务器文件?

在日常运维中,我们常常面临以下场景:两台服务器分别承载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

总结与最佳实践

自动同步两台服务器文件的脚本是运维标准化的重要手段,结合上文,我建议:

  1. 优先选择rsync + cron(非实时场景),稳定且资源消耗低。
  2. 实时场景用inotify + rsync,但注意监控资源,可限速--bwlimit
  3. 双向同步慎用,务必加上--dry-run测试,并做好版本备份。
  4. 日志与告警不可少,否则同步失败可能导致长时间数据不一致。
  5. 定期测试恢复流程,同步脚本本身也应纳入版本管理。

推荐将脚本托管在GitLab/GitHub私有仓库,并使用chmod +x赋予执行权限,配合cron或systemd timer实现无人值守。

延伸阅读:如有需要可参考官方文档,域名示例:rsync官网(rsync.samba.org)和inotify手册(linux.die.net/man/1/inotifywait)。

抱歉,评论功能暂时关闭!