生产环境静态资源双向秒级同步需inotify与rsync协同:inotify作哨兵监听真实变更,rsync作信使传输差异,两端对称部署并隔离事件。

在生产环境部署静态资源双向秒级同步,关键不是堆砌工具,而是让 rsync 和 inotify 各司其职、严丝合缝:inotify 做“哨兵”,只监听真实变更;rsync 做“信使”,只传差异内容;双向不靠单脚跳,而靠两端对称部署+事件隔离。
一、双向同步必须做好的四件基础事
双向≠两套单向简单叠加。没处理好以下四点,极易陷入“文件打架”或“死循环同步”:
-
SSH 免密互信必须双向打通:ng-serv-1 要能免密登录 ng-serv-2,反之亦然。用
ssh-keygen -t rsa生成密钥后,ssh-copy-id -i ~/.ssh/id_rsa.pub root@对方IP执行两次。 -
同步目录需严格隔离监控路径:比如 A 机监控
/app/nginx/conf/,B 机也监控同名路径,但双方 rsync 命令中--exclude必须排除对方正在触发的临时文件(如.swp、~)、日志文件、锁文件,避免触发嵌套调用。 -
rsync 必须启用安全增量参数:固定使用
rsync -avz --delete --exclude='*.log' --exclude='.git' --timeout=30。其中--delete保证删除操作同步,--timeout防止网络卡顿导致 inotifywait 长期阻塞。 - 禁用 rsync 守护进程(rsyncd),统一走 SSH:国产麒麟系统 SELinux 或 auditd 对 rsyncd 端口(873)拦截多、审计日志杂。直接走 SSH(默认22端口),权限清晰、隧道加密、策略统一,运维排查更直接。
二、Inotify 参数与脚本必须调优到生产水位
默认 inotify 限制极低,面对成千上万个静态文件(如前端构建产物),不出三分钟就触发 No space left on device 错误。必须调整内核参数并固化:
- 编辑
/etc/sysctl.conf,追加三行(数值按实际目录规模放大):fs.inotify.max_user_watches = 2097152fs.inotify.max_user_instances = 512fs.inotify.max_queued_events = 32768
执行sysctl -p生效。 - inotifywait 监控命令必须带防抖和过滤:
inotifywait -m -e create,modify,delete,move_self,attrib --format '%w%f %e' -o /dev/stdout /app/nginx/conf/ | while read file event; do [ -f "$file" ] && [ "$event" != "MOVED_TO" ] || continue; sleep 0.1; rsync -avz --delete ...; done
关键点:-m持续监听;--format输出精准路径;sleep 0.1防止高并发写入触发多次;[ -f "$file" ]过滤目录事件;[ "$event" != "MOVED_TO" ]避免编辑器保存时的临时重命名事件重复触发。
三、麒麟系统适配要点(非通用 Linux)
国产麒麟 V10 SP1/SP2 内核为 4.19+,已原生支持 inotify,但默认未安装用户态工具,且部分安全策略影响脚本执行:
-
安装 inotify-tools 必须用源码编译:麒麟官方源中 inotify-tools 版本老旧(常为 3.13),存在
inotifywait在长路径下崩溃问题。建议下载 inotify-tools 3.22.1 源码,执行:./configure --prefix=/usr && make && sudo make install -
systemd 服务需显式声明 CapabilityBoundingSet:若将同步脚本注册为 systemd 服务,必须在
.service文件中加入:CapabilityBoundingSet=CAP_SYS_ADMIN CAP_NET_BIND_SERVICE
否则 inotifywait 可能因权限不足无法挂载 inotify 实例。 -
关闭 auditd 对 rsync 的过度审计(可选):若发现
/var/log/audit/audit.log中大量记录 rsync 系统调用,可在/etc/audit/rules.d/rsync.rules中添加:-a never,exit -F arch=b64 -S execve -F path=/usr/bin/rsync
避免日志刷爆磁盘。
四、上线前必须验证的三个场景
配置完成不等于可用。以下三项必须人工触发并验证日志输出:
-
单文件修改同步:在 A 机执行
echo "#test" >> /app/nginx/conf/nginx.conf,1 秒内 B 机对应文件末尾应出现相同内容,tail -f /var/log/rsync-sync.log显示单次 rsync 成功记录。 -
目录批量新增:在 A 机
mkdir -p /app/nginx/conf/vhost/{a,b,c},B 机应在 2 秒内同步出完整三级结构,且 inotifywait 日志中仅出现 3 条CREATE事件(非每层一个)。 -
冲突模拟(删+改同名文件):A 机删掉
conf.d/app.conf,B 机同时修改它。观察是否仅 A 的删除动作同步过去(B 的修改被覆盖),确认--delete行为符合预期——这是双向同步中“以发起端为准”的设计体现,业务侧需提前约定主从逻辑。










