标签搜索

rsync常用脚本案例分享

mrui
2025-12-08 / 0 评论 / 2 阅读 / 正在检测是否收录...

案例1:网站文件同步

我们需要将本地开发的网站文件同步到生产服务器。(这招也可以用在云计算磁盘需要缩容的过程中,毕竟云硬盘,多开1G都是要花钱的,利用率最大化才是省钱王道)

# 基本同步命令
rsync -avz --delete /var/www/html/ root@192.168.1.100:/var/www/html/
​
# 排除不需要同步的文件
rsync -avz --delete \
  --exclude='*.log' \
  --exclude='cache/' \
  --exclude='.git/' \
  /var/www/html/ root@192.168.1.100:/var/www/html/

这个命令会:

  • 递归同步整个网站目录
  • 保持文件属性和时间戳
  • 压缩传输数据
  • 删除目标目录中多余的文件
  • 排除日志文件、缓存目录和Git仓库

案例2:数据库备份同步

对于数据库备份文件的异地同步,我们通常需要更谨慎的处理。

#!/bin/bash
# 数据库备份同步脚本
​
BACKUP_DIR="/backup/mysql"
REMOTE_HOST="backup-server.company.com"
REMOTE_DIR="/data/mysql-backup"
LOG_FILE="/var/log/backup-sync.log"
​
# 执行同步
rsync -avz --progress \
  --log-file=$LOG_FILE \
  --timeout=300 \
  --bwlimit=10000 \
  $BACKUP_DIR/ root@$REMOTE_HOST:$REMOTE_DIR/
​
# 检查同步结果
if [ $? -eq 0 ]; then
    echo "$(date): 备份同步成功" >> $LOG_FILE
else
    echo "$(date): 备份同步失败" >> $LOG_FILE
    # 发送告警邮件
    echo "备份同步失败,请检查" | mail -s "备份告警" admin@company.com
fi

案例3:配置文件分发

在集群环境中,经常需要将配置文件分发到多台服务器。

#!/bin/bash
# 配置文件分发脚本
​
CONFIG_DIR="/etc/app-config"
SERVERS=("web01" "web02" "web03" "web04")
​
for server in "${SERVERS[@]}"; do
    echo "正在同步配置到 $server..."
    
    rsync -avz --dry-run \
      --exclude='*.bak' \
      $CONFIG_DIR/ root@$server:$CONFIG_DIR/
    
    # 确认无误后执行实际同步
    read -p "确认同步到 $server 吗?(y/n): " confirm
    if [ "$confirm" = "y" ]; then
        rsync -avz \
          --exclude='*.bak' \
          $CONFIG_DIR/ root@$server:$CONFIG_DIR/
        echo "$server 同步完成"
    fi
done

案例4:监控同步状态

#!/bin/bash
# rsync监控脚本

SYNC_LOG="/var/log/rsync-monitor.log"
LOCK_FILE="/var/run/rsync-sync.lock"

# 检查是否已有rsync进程在运行
if [ -f "$LOCK_FILE" ]; then
    echo "$(date): rsync进程已在运行" >> $SYNC_LOG
    exit 1
fi

# 创建锁文件
echo $$ > $LOCK_FILE

# 执行同步并记录时间
START_TIME=$(date +%s)
echo "$(date): 开始同步" >> $SYNC_LOG

rsync -avz --stats /source/ user@remote:/destination/ 2>&1 | tee -a $SYNC_LOG

END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

echo "$(date): 同步完成,耗时 ${DURATION} 秒" >> $SYNC_LOG

# 清理锁文件
rm -f $LOCK_FILE

案例5:配合inotify实现实时同步

inotify是Linux内核提供的文件系统事件监控机制,可以监控文件的创建、修改、删除等操作。配合rsync使用,就能实现准实时的文件同步。

#inotify-tools这个工具包
# CentOS/RHEL
yum install inotify-tools
# Ubuntu/Debian  
apt-get install inotify-tools
#监控脚本
#!/bin/bash
SRC_DIR="/var/www/html"
DEST="user@remote_host:/var/www/html/"
DELAY=5
SYNC_LOCK="/tmp/rsync.lock"

inotifywait -mr --format '%w %f %e' -e modify,create,delete,move $SRC_DIR | while read DIR FILE EVENT
do
    echo "检测到文件变化: $DIR$FILE ($EVENT)"
    
    # 如果已经有同步任务在等待,就跳过
    if [ -f $SYNC_LOCK ]; then
        continue
    fi
    
    # 创建锁文件
    touch $SYNC_LOCK
    
    # 延迟执行同步
    (
        sleep $DELAY
        echo "开始同步..."
        rsync -av --delete $SRC_DIR/ $DEST
        rm -f $SYNC_LOCK
        echo "同步完成"
    ) &
done

注意:inotify监控的文件数量是有限制的,可以通过调整内核参数来增加:

案例6:定时备份脚本

#!/bin/bash
# 完整的定时备份脚本 /usr/local/bin/auto-backup.sh

# 配置参数
SOURCE_DIRS=("/var/www" "/etc" "/home")
BACKUP_SERVER="backup.company.com"
BACKUP_BASE="/backup/$(hostname)"
LOG_DIR="/var/log/backup"
RETENTION_DAYS=7

# 创建日志目录
mkdir -p $LOG_DIR

# 获取当前时间
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="$LOG_DIR/backup_$DATE.log"

# 记录开始时间
echo "=== 备份开始: $(date) ===" > $LOG_FILE

# 检查网络连通性
if ! ping -c 3 $BACKUP_SERVER > /dev/null 2>&1; then
    echo "错误: 无法连接到备份服务器 $BACKUP_SERVER" >> $LOG_FILE
    exit 1
fi

# 备份每个目录
for dir in "${SOURCE_DIRS[@]}"; do
    if [ -d "$dir" ]; then
        echo "正在备份 $dir..." >> $LOG_FILE
        
        # 创建远程目录
        ssh root@$BACKUP_SERVER "mkdir -p $BACKUP_BASE$(dirname $dir)"
        
        # 执行同步
        rsync -avz --delete \
            --exclude='*.tmp' \
            --exclude='*.log' \
            --exclude='cache/' \
            --timeout=3600 \
            --log-file=$LOG_FILE \
            $dir/ root@$BACKUP_SERVER:$BACKUP_BASE$dir/
        
        if [ $? -eq 0 ]; then
            echo "$dir 备份成功" >> $LOG_FILE
        else
            echo "$dir 备份失败" >> $LOG_FILE
            # 发送告警
            echo "目录 $dir 备份失败" | mail -s "备份失败告警" admin@company.com
        fi
    else
        echo "警告: 目录 $dir 不存在" >> $LOG_FILE
    fi
done

# 清理旧日志
find $LOG_DIR -name "backup_*.log" -mtime +$RETENTION_DAYS -delete

echo "=== 备份结束: $(date) ===" >> $LOG_FILE

# 设置定时任务
# crontab -e
# 0 2 * * * /usr/local/bin/auto-backup.sh

案例7:代码部署脚本

#!/bin/bash
# 代码部署脚本

PROJECT_NAME="myapp"
LOCAL_PATH="/var/jenkins/workspace/$PROJECT_NAME"
SERVERS=("web01.company.com" "web02.company.com")
REMOTE_PATH="/var/www/$PROJECT_NAME"
BACKUP_PATH="/var/www/backup/$PROJECT_NAME"

echo "开始部署 $PROJECT_NAME..."

# 检查本地代码是否存在
if [ ! -d "$LOCAL_PATH" ]; then
    echo "错误: 本地代码路径不存在"
    exit 1
fi

# 部署到每台服务器
for server in "${SERVERS[@]}"; do
    echo "正在部署到 $server..."
    
    # 创建备份
    ssh root@$server "
        mkdir -p $BACKUP_PATH
        if [ -d $REMOTE_PATH ]; then
            cp -r $REMOTE_PATH $BACKUP_PATH/$(date +%Y%m%d_%H%M%S)
        fi
    "
    
    # 同步代码
    rsync -avz --delete \
        --exclude='.git/' \
        --exclude='node_modules/' \
        --exclude='*.log' \
        $LOCAL_PATH/ root@$server:$REMOTE_PATH/
    
    if [ $? -eq 0 ]; then
        echo "$server 部署成功"
        
        # 重启服务
        ssh root@$server "systemctl restart $PROJECT_NAME"
        
        # 健康检查
        sleep 5
        if curl -f http://$server/health > /dev/null 2>&1; then
            echo "$server 服务启动正常"
        else
            echo "$server 服务启动异常,正在回滚..."
            # 回滚操作
            LATEST_BACKUP=$(ssh root@$server "ls -t $BACKUP_PATH | head -1")
            ssh root@$server "
                rm -rf $REMOTE_PATH
                cp -r $BACKUP_PATH/$LATEST_BACKUP $REMOTE_PATH
                systemctl restart $PROJECT_NAME
            "
        fi
    else
        echo "$server 部署失败"
    fi
done

echo "部署完成"

案例8:

#同步状态监控
#!/bin/bash
# rsync状态监控脚本

MONITOR_LOG="/var/log/rsync-monitor.log"
ALERT_EMAIL="admin@company.com"

check_rsync_status() {
    local log_file=$1
    local max_age_hours=2
    
    if [ ! -f "$log_file" ]; then
        echo "告警: 同步日志文件不存在"
        return 1
    fi
    
    # 检查日志文件是否太旧
    if [ $(find "$log_file" -mmin +$((max_age_hours * 60)) | wc -l) -gt 0 ]; then
        echo "告警: 同步日志超过 $max_age_hours 小时未更新"
        return 1
    fi
    
    # 检查是否有错误
    if grep -q "rsync error\|failed\|No such file" "$log_file"; then
        echo "告警: 同步过程中发现错误"
        return 1
    fi
    
    return 0
}

# 检查各个同步任务
SYNC_LOGS=("/var/log/web-sync.log" "/var/log/db-sync.log" "/var/log/config-sync.log")

for log in "${SYNC_LOGS[@]}"; do
    if ! check_rsync_status "$log"; then
        echo "$(date): $log 检查失败" >> $MONITOR_LOG
        # 发送告警邮件
        tail -50 "$log" | mail -s "Rsync同步告警: $(basename $log)" $ALERT_EMAIL
    fi
done
0

评论 (0)

取消