七牛云OSS通过s3fs挂载与实时同步(一键脚本/推荐)

一、 脚本功能简介

该脚本是一个七牛云S3FS挂载与实时同步的一键配置工具,主要功能如下:

1. 基础环境准备

  • 脚本仅适用于Centos7,可选更换为阿里云YUM源
  • 自动安装必要软件:
    • s3fs-fuse(用于挂载对象存储)
    • rsync + inotify-tools(用于实时同步)
    • 其他依赖(fusewgetcurl等)

2. 七牛云S3FS挂载

    • 通过交互式输入配置参数:
      • 七牛云AccessKey/SecretKey
      • Bucket名称和S3域名(如 https://s3.cn-east-1.qiniucs.com
      • 本地挂载目录(如 /data/blog_html
    • 自动完成以下操作:
      • 创建密钥文件并设置权限
      • 禁用SELinux(避免挂载冲突)
      • 挂载七牛云存储到本地目录
      • 配置Systemd服务实现开机自动挂载

3. 实时目录同步

  • 单向同步:将本地源目录(如 /opt/public_static)实时同步到挂载目录(/data/blog_html
  • 同步逻辑:
    • 全量同步:首次运行时会完整同步所有文件
    • 增量同步:监控源目录的创建、修改、删除、移动事件,实时同步变更
    • 精确处理:文件/目录的增删改移均会同步,确保两端完全一致
  • 日志记录:所有操作记录到 /var/log/qiniu_sync/sync_*.log

4. 服务化管理

  • 通过Systemd管理同步服务:
    • 自动重启(异常退出时)
    • 开机自启
    • 日志状态查看(systemctl status sync_blog

5. 验证与卸载

  • 提供挂载状态检查命令(mount | grep s3fs
  • 支持卸载S3FS挂载(通过umount命令)

6. 典型使用场景

  • WordPress静态文件同步:将网站生成的静态文件(如/opt/public_static)实时同步到七牛云对象存储(通过挂载目录/data/blog_html)。
  • 双向同步效果:由于S3FS已挂载,本地对/data/blog_html的变更会自动同步到云端,反之亦然(需依赖S3FS的缓存机制)。

7. 注意事项

  • 权限问题:确保挂载目录可被Web服务(如Nginx/PHP)访问。
  • 首次同步:若文件量大,首次同步可能较慢。
  • 删除操作:同步时会镜像删除操作(谨慎使用)。
  • 日志排查:若同步失败,优先检查 /var/log/qiniu_sync/ 下的日志文件。
  • 费用警告:S3FS 默认会频繁向云端发送请求以维护文件系统一致性(如检查文件状态、元数据等),即使文件未被实际访问,所以请求数会飙升,要注意费用,【解决方案(未测试):增加缓存参数:在挂载命令中添加 -o stat_cache_expire=86400 -o attr_cache_expire=86400(单位:秒),减少元数据请求频率!

8. 命令速查

# 查看同步日志
tail -f /var/log/qiniu_sync/sync_*.log

# 手动重启服务
systemctl restart sync_blog

# 卸载S3FS(谨慎操作)
umount /data/blog_html && systemctl disable s3fs-mount

二、脚本内容

下载脚本:https://gitee.com/cncsrf/qiniu-rsync
#!/bin/bash
# ========================================================
# 七牛云S3FS挂载与实时同步一键配置脚本
# 功能:
# 1. 脚本仅适用于Centos7,可选更换阿里云YUM源加速安装
# 2. 自动安装s3fs-fuse/rsync/inotify-tools等必要软件
# 3. 配置七牛云对象存储通过S3FS挂载到本地目录
# 4. 设置inotify+rsync实现目录实时同步
# 5. 自动配置systemd服务实现开机自启
# 
# 使用前请准备:
# - 七牛云的AccessKey/SecretKey
# - Bucket名称和S3域名
# - 确保以root用户执行
# ========================================================

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# 检查是否为root用户
if [ "$(id -u)" -ne 0 ]; then
    echo -e "${RED}错误:此脚本需要以root用户身份运行${NC}"
    exit 1
fi

# 欢迎信息
echo -e "${GREEN}=== 七牛云S3FS挂载与实时同步一键脚本 ===${NC}"
echo -e "${YELLOW}本脚本将自动完成以下操作:"
echo "1. 安装必要软件(s3fs, rsync, inotify-tools)"
echo "2. 配置七牛云S3FS挂载"
echo "3. 设置实时目录同步"
echo -e "=============================================${NC}"

# 询问是否更换阿里云YUM源
read -p "是否要更换为阿里云YUM源以提高下载速度?(y/n): " change_yum
if [[ $change_yum =~ ^[Yy] ]]; then
    echo -e "${GREEN}正在更换为阿里云YUM源...${NC}"
    # 备份原有源
	yum install wget -y
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2>/dev/null
    mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup 2>/dev/null
    
    # 下载阿里云源(适配CentOS 7)
    wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    
    # 清理并生成缓存
    yum clean all && yum makecache
    echo -e "${GREEN}YUM源已更换为阿里云镜像${NC}"
fi

# 交互式参数输入
echo -e "\n${YELLOW}请输入配置信息:${NC}"
read -p "七牛云AccessKey: " qiniu_access_key
read -p "七牛云SecretKey: " qiniu_secret_key
read -p "七牛云Bucket名称(如hx99-blog): " qiniu_bucket
read -p "七牛云S3域名(如https://s3.cn-east-1.qiniucs.com): " qiniu_url
read -p "本地挂载目录(如/data/blog_html): " mount_dir
read -p "要同步的源目录(如/opt/1panel/apps/wordpress/MyBlog-wordpress/data/public_static): " source_dir

# 自动创建目录
echo -e "\n${GREEN}正在创建目录...${NC}"
mkdir -p "$mount_dir" || { echo -e "${RED}创建挂载目录失败${NC}"; exit 1; }
mkdir -p "$source_dir" || { echo -e "${RED}创建源目录失败${NC}"; exit 1; }
echo -e "目录创建完成: \n- 挂载目录: ${mount_dir}\n- 源目录: ${source_dir}"

# 安装必要软件
echo -e "\n${GREEN}[1/4] 正在安装必要软件...${NC}"
yum install -y epel-release
yum makecache
yum install -y fuse s3fs-fuse wget unzip curl rsync inotify-tools || { 
    echo -e "${RED}软件安装失败,请检查YUM源配置${NC}"
    exit 1
}
echo -e "${GREEN}所有软件安装完成${NC}"

# 配置S3FS
echo -e "\n${GREEN}[2/4] 正在配置S3FS...${NC}"
echo "${qiniu_access_key}:${qiniu_secret_key}" > /etc/.passwd-qiniu
chmod 600 /etc/.passwd-qiniu

# 临时禁用SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

# 挂载S3存储
echo -e "${YELLOW}正在挂载S3存储...${NC}"
s3fs "$qiniu_bucket" "$mount_dir" -o url="$qiniu_url" -o passwd_file=/etc/.passwd-qiniu -o allow_other -o umask=022 -o nonempty || { 
    echo -e "${RED}S3FS挂载失败,常见原因:${NC}"
    echo "1. 密钥错误"
    echo "2. Bucket名称或域名不正确"
    echo "3. 网络连接问题"
    echo "4. Bucket权限设置问题"
    exit 1
}
echo -e "${GREEN}S3FS挂载成功${NC}"

# 设置开机自动挂载
echo -e "\n${GREEN}[3/4] 设置开机自动挂载...${NC}"
cat > /etc/systemd/system/s3fs-mount.service <<EOF
[Unit]
Description=Mount Qiniu Cloud Storage via S3FS
After=network.target
Requires=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/s3fs $qiniu_bucket $mount_dir \\
-o url=$qiniu_url \\
-o passwd_file=/etc/.passwd-qiniu \\
-o allow_other \\
-o umask=022 \\
-o nonempty \\
-o dbglevel=info
ExecStop=/bin/fusermount -u $mount_dir
RemainAfterExit=true

[Install]
WantedBy=multi-user.target
EOF

chmod 644 /etc/systemd/system/s3fs-mount.service
systemctl daemon-reload
systemctl enable s3fs-mount --now
echo -e "${GREEN}开机自动挂载已设置${NC}"

# 配置实时同步
echo -e "\n${GREEN}[4/4] 配置实时同步...${NC}"
# 创建同步日志目录
mkdir -p /var/log/qiniu_sync
log_file="/var/log/qiniu_sync/sync_$(date +%Y%m%d).log"

cat > /usr/local/bin/sync_blog.sh <<EOF
#!/bin/bash

# 源目录和目标目录
SOURCE_DIR="$source_dir"
TARGET_DIR="$mount_dir"

# 日志文件
LOG_FILE="$log_file"

# 确保目录存在
mkdir -p "\$TARGET_DIR"

# 更可靠的同步函数
sync_file() {
    local src="\$1"
    local rel_path="\${src#\$SOURCE_DIR/}"
    local dst="\$TARGET_DIR/\$rel_path"
    
    # 如果是删除操作
    if [ ! -e "\$src" ]; then
        if [ -e "\$dst" ]; then
            rm -rf "\$dst"
            echo "\$(date '+%Y-%m-%d %H:%M:%S') [DELETE] 已删除: \$dst" >> "\$LOG_FILE"
        fi
        return
    fi
    
    # 如果是目录则创建
    if [ -d "\$src" ]; then
        mkdir -p "\$dst"
        return
    fi
    
    # 文件同步(保留权限和时间戳)
    rsync -aq "\$src" "\$dst" && \\
    echo "\$(date '+%Y-%m-%d %H:%M:%S') [SYNC] 同步: \$src → \$dst" >> "\$LOG_FILE"
}

# 首次全量同步
echo "\$(date '+%Y-%m-%d %H:%M:%S') 开始首次同步..." >> "\$LOG_FILE"
rsync -av --ignore-existing "\$SOURCE_DIR/" "\$TARGET_DIR/" >> "\$LOG_FILE" 2>&1
echo "\$(date '+%Y-%m-%d %H:%M:%S') 首次同步完成" >> "\$LOG_FILE"

# 持续监控变化
inotifywait -m -r --format '%w%f %e' -e create -e modify -e delete -e move "\$SOURCE_DIR" |
while read FILE EVENT; do
    echo "\$(date '+%Y-%m-%d %H:%M:%S') 检测到变化: \$FILE (\$EVENT)" >> "\$LOG_FILE"
    
    case "\$EVENT" in
        *"CREATE"*|*"MODIFY"*|*"MOVED_TO"*)
            sync_file "\$FILE"
            ;;
        *"DELETE"*|*"MOVED_FROM"*)
            sync_file "\$FILE"  # 会触发删除逻辑
            ;;
    esac
done
EOF

chmod +x /usr/local/bin/sync_blog.sh

# 创建同步服务
cat > /etc/systemd/system/sync_blog.service <<EOF
[Unit]
Description=Sync Blog Static Files
After=network.target s3fs-mount.service

[Service]
ExecStart=/usr/local/bin/sync_blog.sh
Restart=always
RestartSec=5
User=root

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable sync_blog --now

# 完成信息
echo -e "\n${GREEN}=== 安装完成 ===${NC}"
echo -e "${YELLOW}配置摘要:${NC}"
echo "七牛云Bucket: $qiniu_bucket"
echo "挂载目录: $mount_dir"
echo "同步源目录: $source_dir"
echo -e "\n${GREEN}服务状态:${NC}"
echo -e "S3FS挂载状态:"
mount | grep s3fs
echo -e "\n同步服务状态:"
systemctl status sync_blog --no-pager
echo -e "\n${YELLOW}后续操作:${NC}"
echo "1. 查看实时同步日志: tail -f $log_file"
echo "2. 手动重启同步服务: systemctl restart sync_blog"
echo "3. 卸载S3FS: umount $mount_dir && systemctl disable s3fs-mount"
echo -e "\n${GREEN}所有操作已完成!${NC}"