自动实时同步文件
在Linux系统中,有时需要同步文件或目录(当然目录也是文件)。
你可能会使用scp等命令;如果文件很多,考虑网络中断等异常因素,你可能会使用rsync增量同步。
如果要实时同步呢?你可能会使用定时任务,但定时任务周期粒度是分;写个循环?可能会导致CPU使用率飙升。
我们看一个具体的例子:有两台nginx主机,修改配置后,重新加载并同步到另一台。
我们使用一个简单有效的方案:inotify + rsync
inotify 介绍
从文件管理器到安全工具,文件系统监控对于许多程序来说都是必不可少的。从 Linux 2.6.13 内核开始,Linux 就推出了 inotify,允许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动、重命名、删除、创建或者改变属性。
开工
实施思路是inotify 监控目录状态,发现新建、修改、删除文件后
1. 备份
2. 同步
3. reload
安装 inotify-tools : yum -y install inotify-tools
我们使用inotifywait命令来监视文件状态的改变。
语法:
inotifywait [-hcmrq] [-e
我们常用的参数是 -r 递归监视目录 -e 创建、删除、修改事件
-r, --recursive
Watch all subdirectories of any directories passed as arguments.
-e <event>, --event <event>
Listen for specific event(s) only. If omitted, all events
are listened for.
rsync 也可以使用yum安装,常用的参数是 av,不要想多了,a是all的意思,包括递归、保留时间戳等全部信息
主机之间先建立好信任关系,更加方便同步文件。
细节方面,nginx reload 前,先检查配置文件,确保没有语法错误再加载。
完整实现方案代码如下:
# 0. trust relationship between hosts
# 1. backup configurations
# 2. rsync
# 3. reload
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PEERHOST=10.1.1.2
backupDIR=~/nginxConfigurationBak
[ ! -d $backupDIR ] && mkdir $backupDIR
# haproxyCFG=/wls/haproxy/config/haproxy.cfg
nginxDIR=/wls/nginx/conf
nginxHttpDIR=$nginxDIR/http.d
nginxConfDIR=$nginxDIR/conf.d
reloadCOMMAND="/wls/nginx/sbin/nginx -s reload"
confTestCommand="/wls/nginx/sbin/nginx -t"
cd $nginxDIR || exit 1
while inotifywait -r -e modify,create,delete --exclude ".*(\.git|\.idea)" $nginxHttpDIR $nginxConfDIR; do
# while inotifywait -r -e modify,create,delete --exclude ".*(\.git|\.idea)" $nginxDIR; do
# 1. backup
# (cd $backupDIR && mkdir $(date +%F))
cd $backupDIR || exit 2
[ ! -d $(date +%F) ] && mkdir $(date +%F)
cd $(date +%F) || exit 3
rsync -av --delete $nginxHttpDIR .
rsync -av --delete $nginxConfDIR .
# 2. rsync
rsync -av --delete $nginxHttpDIR/ $PEERHOST:$nginxHttpDIR
rsync -av --delete $nginxConfDIR/ $PEERHOST:$nginxConfDIR
# rsync -av --delete $nginxHttpDIR/ $SLAVEHOST:`pwd`
# 3. reload
# test configurations and reload
$confTestCommand && $reloadCOMMAND
# peer reload
$confTestCommand && ssh $PEERHOST "$reloadCOMMAND"
# $confTestCommand && $reloadCOMMAND && ssh $PEERHOST "$COMMAND"
done