跨服務器同步百 GB 級數據時,網絡抖動、進程被殺、磁盤 IO 瓶頸常導致 rsync 中斷。本文提供一個**輕量級監控腳本**,周期性檢查目標目錄大小與 rsync 進程狀態,自動重啟中斷傳輸,確保數據最終一致性。
/var/www/vhosts/(目標大小 ~11517 MB)/root/rsync.sh 中/root/monitor_rsync.sh#!/bin/bash
# 每 5 分鐘通過 cron 執行:*/5 * * * * /root/monitor_rsync.sh
TARGET_DIR="/var/www/vhosts"
EXPECTED_SIZE_MB=11517 # 源端實際大小,建議動態獲取
RSYNC_SCRIPT="/root/rsync.sh"
LOG_FILE="/var/log/rsync_monitor.log"
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"; }
# 1. 獲取當前目錄大小 (MB)
current_size=$(du -sm "$TARGET_DIR" 2>/dev/null | awk '{print $1}')
# 2. 檢查 rsync 進程數
rsync_pids=$(pgrep -x rsync)
rsync_count=$(echo "$rsync_pids" | grep -c '^')
if [[ "$current_size" -ge "$EXPECTED_SIZE_MB" ]]; then
log "✅ 目錄大小達標 ($current_size MB >= $EXPECTED_SIZE_MB MB),傳輸完成。"
exit 0
fi
log "📦 當前大小: $current_size MB (目標: $EXPECTED_SIZE_MB MB),rsync 進程數: $rsync_count"
if [[ $rsync_count -eq 0 ]]; then
log "⚠️ rsync 未運行,嘗試重新啟動..."
nohup sh "$RSYNC_SCRIPT" >> "$LOG_FILE" 2>&1 &
log "🚀 已在後台啟動 rsync.sh (PID: $!)"
elif [[ $rsync_count -eq 1 ]]; then
log "🏃 rsync 正在運行 (PID: $rsync_pids),繼續等待..."
else
log "⚠️ 檢測到多個 rsync 進程 ($rsync_count),可能有殭屍進程,清理後重啟"
kill -9 $rsync_pids 2>/dev/null
sleep 2
nohup sh "$RSYNC_SCRIPT" >> "$LOG_FILE" 2>&1 &
log "🔄 已清理並重啟 rsync"
fi
/root/rsync.sh(支持斷點續傳)#!/bin/bash
SRC="user@source-server:/var/www/vhosts/"
DEST="/var/www/vhosts/"
# -a 歸檔模式,-z 壓縮,-P 顯示進度+斷點續傳,--delete 目標端刪除源端已刪除文件
rsync -azP --delete --bwlimit=50000 "$SRC" "$DEST"
# --bwlimit 限速 50MB/s,避免佔滿帶寬影響業務
chmod +x /root/monitor_rsync.sh /root/rsync.shcrontab -e 添加:*/5 * * * * /root/monitor_rsync.shtail -f /var/log/rsync_monitor.log| 局限 | 增強方案 |
|---|---|
| 固定期望大小,源端變化需手動更新 | 腳本啟動時 ssh source "du -sm /var/www/vhosts" 動態獲取 |
| 無校驗文件完整性 | 傳輸後運行 rsync -azc --dry-run 校驗 checksum |
| 單進程,無法利用多核/多隊列 | 使用 parallel-rsync、pssh 或拆分目錄並發 |
| 殭屍進程檢測簡陋 | 結合 ps -o stat 判斷 Z 狀態,或用 systemd 管理 rsync 服務 |