CentOS 6.5 inotify+rsync 部署

前端之家收集整理的这篇文章主要介绍了CentOS 6.5 inotify+rsync 部署前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Rsync是一款远程同步软件,在同步文件文件和目录)的时候可以保持原文件的权限、修改时间、包括链接文件也可以同步。

这个东西应用在什么地方呢?不管你是什么业务,如果你有几十台以上的服务器,并且这些服务器需要实时保持拥有的文件一致,那你就会用到这个工具。比如你有几十台web服务器,网页文件会经常修改,如何批量同步这些新的网页文件到所有服务器上呢?


Inotify又是什么呢?它是一种通知机制,随着时间的推移,你的原文件夹可能越来越大,如果每次同步都把整个目录扫描一遍那简直不敢想象,inotify就是内核提供的一种功能,可以实现对目录的监控,如果该目录有任何文件删除修改、新建它都会捕捉到这一动作,并可以把这一事件发送给其他应用程序。

主机名 IP 说明
Linux01.localhost
10.10.6.12
推送文件
Linux02.localhost 10.10.6.15
运行rsync守护进程,作为Server端,接收推送。

说明:这个模式你要了解,不是服务器端向客户端推送数据,是客户端其实就是使用rsync工具向运行rsync服务的服务器端推送数据。所以一般运行的Web服务器上都安装此服务,用于接收页面文件的更新。


安装Rsync

实现原理:

rsync采用的是C/S结构,不过S端是服务器端,运行rsync的守护进程,C端通过命令来向S端推送文件

安装:

rpm-qarsync#检查是安装了rsync
rpm-ersync#如果安装了,那么就删除,系统自带的版本比较低
wgethttps://download.samba.org/pub/rsync/rsync-3.1.2.tar.gz--no-check-certificate

wKiom1ggOQPTaOL6AABLKuR6Ss0298.jpg-wh_50

wKioL1ggOQXjVSeVAADXf7CR8vw300.jpg-wh_50

tar-xzfrsync-3.1.2.tar.gz
cdrsync-3.1.2
./configure--prefix=/usr/local/rsync--disable-ipv6

wKiom1ggPhug-F3vAABntIlYpq0354.jpg-wh_50

wKioL1ggPhvALmp9AABje6vAKAg056.jpg-wh_50

如果不指定安装目录,则默认会安装到如下目录中:

wKioL1ggPlmzhIZSAABN5Is9DTc296.jpg-wh_50

make&&makeinstall

设置账户和目录:

groupadd-rrsync#创建rsync系统组
useradd-grsyncrsync-r-s/sbin/login#创建rsync系统账号并加入到rsync组

wKiom1ggNoLig1X_AABWZiegTDA944.jpg-wh_50

mkdirbackup#创建用于接收推送文件的目录
chownrsync.rsync./backup#设置改目录的属主和属组位rsync

wKiom1ggNxXggiRUAADIk8kcfNc126.jpg-wh_50

编辑配置文件:编译安装后它使用的配置文件默认位置为/etc/rsyncd.conf,但是默认这个文件并不存在,需要你手动建立。

touch/etc/rsyncd.conf#守护进程使用的配置文件,必须是rsyncd.conf
touch/etc/rsyncd.passwd#用户名和密码文件,这个名字可以随便
chmod600/etc/rsyncd.passwd#修改密码文件权限

wKiom1ggRB2wCspQAABUd-0nTYw624.jpg-wh_50

vim/etc/rsyncd.conf#编辑配置文件
#[全局配置]
#服务器IP和监听端口号
address=10.10.6.15
port=873
#服务器传输文件时服务器用哪个属主和属组去保存接收到的文件,也就是权限替换,如果在这里设
#置成root,则会保留权限。
uid=rsync
gid=rsync
#在文件传输之前,服务器守护进程将chroot到指定的PATH,优点是实时特殊的保护,缺点是需要roo#t权限
usechroot=no
#最大并发数
maxconnection=10
#超时时长
timeout=300
#锁、日志和pid文件位置
lockfile=/var/run/rsync.lock
logfile=/var/run/rsync.log
pidfile=/var/run/rsync.pid
#消息文件,当客户端连接到服务器是该文件内容将会显示给客户端,这个文件不是必须的
motdfile=/etc/rsyncd.mod
#存放虚拟用户和密码的文件
secretsfile=/etc/rsyncd.passwd
#允许的网段
hostsallow=*
#不允许的网段
#hostsdeny=0.0.0.0/32
#是否允许客户上传文件,true不允许,false允许。
readonly=false

#[模块配置],所谓模块配置其实就是要使用的目录,客户端推送文件到服务器端的哪个目录
[backup]
#需要接收同步的目录
path=/usr/local/backup
#是否忽略错误
ignoreerrors
list=false
#虚拟的用户,也就是客户端用那个用户来连接服务器,可以用空格或者逗号分隔多个用户,该用户
#必须在上面secretsfile=/etc/rsyncd.passwd文件中
authusers=rsync_backup
#该模块的描述,客户端连接后会显示给客户端
commment=hello
vim/etc/rsyncd.passwd#编辑密码文件

wKioL1ghZ1Ozt45jAABAukkst6Y239.jpg-wh_50

./rsync--daemon#启动服务

wKiom1ghZ9DROs0VAABvCzOYqFA300.jpg-wh_50

说明:rsync可以以守护进程的方式运行,也可以由xinetd来激活,如果你的服务器负载比较高建议rsync以独立的守护进程方式来运行。区别在于,如果以独立的守护进程方式运行,它会一直监听端口随时准备接受文件推送,如果由xinetd这个超级进程来管理的话,那没有推送的时候rsync是休眠状态,当有推送的时候,由xinetd这个超级进程激活rsync,对于繁忙的服务器来说这种方式会有额外开销。

连接测试:

在数据源服务器,这里的环境是Linux01,安装rsync。步骤同上。

touch/etc/rsyncd.passwd#建立密码文件
echo"123456">/etc/rsyncd.passwd#这个文件仅存储密码,服务器端和用户名对应的密码
chmod600/etc/rsyncd.passwd#修改权限

wKioL1ghbiagxOzfAABo32VYdFA846.jpg-wh_50

参数 说明
-v 显示执行过程中的详细信息
-a 归档模式,以递归方式传送文件,并保持文件所有属性,相当于rlptgoD
-r 对子目录以递归模式处理
-R 使用相对路径
-b

创建备份,如果目标有相同文件名是,在覆盖前,先对老文件进行重命名操作。

--backup-dir将文件备份到指定目录,如果不指定目录则在被同步的目录下建立同名备份,不过名字上会多一个~。

-l
保留软连接
-H
保留硬链接
-p
保持文件权限
-o
保持文件属主信息
-g
保持文件属组信息
-t 保留文件时间
-D 保持设备文件信息
--include-from= 文件中读取需要传输的文件或者目录列表,文件内容为一行一个,如果包含的文件或者目录名称中文,要把该文件用UTF-8格式保存
--include= 指定哪些文件或者目录需要传输
--exclude-from= 文件中读取要排除的文件或者目录,文件内容为一行一个,如果排除的文件或者目录名称中文,要把该文件用UTF-8格式保存
--eclude= 指定排除哪些文件或者目录
--progress
显示传输过程
--password-file=
指定密码文件路径
--port= 如果rsyncServer使用非标准端口,那么你在用客户端连接的时候就要指定端口

发送文件

wKioL1ghg0ngPEczAACqxrj_TSE806.jpg-wh_50

查看接收到的文件

wKioL1ghg3TQWohmAAA9mOgKqXI941.jpg-wh_50

有没有注意到权限问题?发送文件的时候hello的属主和属组是chen,但是发送过去以后就变成rsync了。因为我们知道-a参数的含义是保留权限、属主和属组,那为什么传递过去之后就变了呢?

原因就在于配置文件里面的uid和gid设置,看下图:

@L_404_13@

这样的设置结果就是文件同步到服务器端以后,rsync服务器器会根据这个设置来修改文件的属主和属组信息,如果把这里写成root那么rsync就会修改属主和属组了,而会保留信息。

我们修改成root再测试一下

wKiom1ghkpKRyvdHAAB4hkWJfP8889.jpg-wh_50

wKioL1ghkpXyudYGAAA_lVKUP3w814.jpg-wh_50

你会发现权限一样、时间一样、属主和属组也一样。

注意:前提也得是你服务器端有这个同名账户才行,如果没有,这里你查看到的就仅仅是一串数字,也就是权限信息。

下面我更新一下Liux01主机上的hello文件

wKiom1ghmEOgKxqSAABNk2ZmQ_0818.jpg-wh_50

下图是在Linux02上也就是rsync服务器端看到的hello文件内容

wKioL1ghk7uDOnAjAAA54MzQODQ153.jpg-wh_50

在Linux01上执行命令

rsync-avz-b--backup-dir=/aaahello--progressrsync_backup@10.10.6.15::backup--password-file=/etc/rsyncd.passwd

如果要同步目录的话,就把上面的hello文件换成目录

wKiom1ghmPbD2Jj4AACOAEKfx5I283.jpg-wh_50

可以看到服务器端的hello文件已经更新了,并且在该目录下还建立了一个目录,里面放了是没有更新之前的hello文件

wKioL1ghmPfwVaqkAABJjC7C82U579.jpg-wh_50

因为我们加了一个-d的参数,这个参数就是对同名文件更新前先备份,备份到--backup-dir=指定目录,如果没有就新建一个。

现在我们说一下如何关闭rsync进程,它如果作为守护进程来运行的话,你得手动KILL掉进程,然后删除PID文件才行。为了方便我们写一个脚本来执行上述操作

#/bin/bash
#

#该脚本的执行前提是你的rsync服务端配置文件要是/etc/rsyncd.conf,如果不是,请替换成实际位
#置

#从配置文件获取PID文件位置
PIDFILE=`cat/etc/rsyncd.conf|grep'pidfile'|awk-F'''{print$4}'`
#echo$PIDFILE
#判断该文件是否存在
if[-e$PIDFILE];then
cat$PIDFILE|xargskill-9
rm-rf$PIDFILE
echo"rsync服务已经关闭。"
else
echo"当前系统没有运行rsync服务。"
fi

我们知道通过这个rsync是为了实现批量同步,但是我们发现同步命令一次指定同步一台主机,如何做到批量同步多台主机呢?rsync本身没有这个功能,需要自己写脚本实现:

首先准备一个服务器IP列表的文件文件格式如下:

wKioL1gitvHgmmUqAAAxaRXrtz0531.jpg-wh_50

其次写一个执行批量同步的脚本,并且能区分是删除还是其他更新操作

#/bin/bash
#

#该参数是服务器IP列表文件
SERVERLIST=$1

#源目录
SRC_DIR=data
#目标目录
DES_DIR=backup
#目标服务器上的用于备份的目录,该目录用于备份更新时出现同名文件的时候
BACKUP_DIR=/backup/aaa
#连接服务器使用的用户名
USER=rsync_backup


#判断文件是否存在
if[-e$1];then
#读取逐行读取文件
forlinein$(cat$SERVERLIST);do
echo$line
if[$2='DELETE'];then
result=`rsync-avz-b--backup-dir=$BACKUP_DIR$SRC_DIR--delete$USER@$line::$DES_DIR--password-file=/etc/rsyncd.passwd>>/dev/null`
else
result=`rsync-avz-b--backup-dir=$BACKUP_DIR$SRC_DIR$USER@$line::$DES_DIR--password-file=/etc/rsyncd.passwd>>/dev/null`
fi
if$result;then
echo"推送文件到服务器:$line成功。"
else
echo"推送文件到服务器:$line失败。"
fi
done
else
echo"服务器IP列表文件不存在。"
fi

wKioL1giv8vBS8rVAABINDGK7WI883.jpg-wh_50

对rsync各种参数的测试,我看到的也是别人转的,所以把链接贴在这里rsync深入分析

上面都是基于手动运行脚本或命令来进行同步的,那能否自动化执行呢?简单的办法是就是把命令或脚本加入到计划任务重crontab,或者使用inotify,我们推荐使用inotity,因为它不是单一定期的执行推送,关键它可以变化。


安装Inotify:

Inotify它是Linux内核的一个特性,在内核2.6.13开始引入该机制,用于监控文件系统的操作,比如读取、写入和创建等等,当它获取到这些操作以后以后通知应用程序。

首先看看当前系统是否支持

wKiom1gix_WT18lVAACEJifqGwk566.jpg-wh_50

下载工具inotify-tools,这个为是Linux下inotify文件监控工具提供的C开发库函数,同时也包含一系列的命令行工具,使用这些工具可以来做监控文件系统的事件。它提供两种工具:

wget--no-check-certificate
如果遇到SSL无法连接之类的,请升级wget
tar-zxfinotify-tools-3.14.tar.gz
cdinotifi-tools-3.14
/configure--prefix=/usr/local/inotify
make&&makeinstall

inotifywait命令参数:

参数 说明
--fromfile 文件读取需要监视或者排除的文件或目录,一个文件一行,排除的文件以@开头
-m 针对事件持续监听,如果不加该参数那么获取一次事件后就退出了。
-d 运行在后台
-r 递归监控目录
-o 输出事件到文件中,而不是输出到STDOUT
-s 输出错误到系统日志中,而不是输出到STEDRR
-q 除了输出事件之外,不显示其他信息
超时时间
--format

设置事件输出格式

%w 表示发生事件的目录

%f 表示发生事件的文件

%e 所发生的事件

%Xe 事件以X分隔

%T 使用由-timefmt定义的时间格式

--timefmt

指定时间输出格式,用于-fromat选项中的%T格式

%y-%m-%d %H:%M

-excludei 排除文件或目录,不区分大小写
-e -event

如果使用该参数,你就需要手动指定要监控的事件,多个事件用逗号分隔

inotifywatch命令参数:

说明
-fromfile -z 输出表格的行和列
同上
-e 设置指定的监听事件,具体事件同上
-r 递归监视
-a
以指定事件的升序排列
-d
以指定事件的降序排列

要实现监控,并且捕捉文件变化,然后根据变化来进行同步,这里主要是思路问题:

  • 首先我们要把对文件或者目录的操作分成2大类,一是删除和移动、二是其他(包括建立、修改),因为这两类不同操作对于要执行的rsync语句所带的参数不同

  • 其次要通过inotifywait来监控指定的目录,并获取那些文件或目录发生了哪些变化

  • 最后根据这些捕捉的变化来执行rsync语句

我们这里先测试一下inotifywait的效果,为了让inotifywait可以直接执行请修改环境变量。

监控脚本

#/bin/bash
#

inotifywait-mrq-emodify,create,move,delete--fromfile'/tmp/filelist'--timefmt'%y-%m-%d%H:%M'--format'%T%w%f%e'--outfile'/tmp/i.log'

要监控的目录列表文件

wKioL1gi6TPiHeoqAAA4wWJa1dg792.jpg-wh_50

测试,这个脚本目前是在前台运行,所以是这种状况,你也可以设置为后台运行,只要在脚本后面加一个 &

wKioL1gi6Wqi7tu6AAAtuBr7V5U590.jpg-wh_50

wKiom1gi6fnxbF-CAADRL08q434541.jpg-wh_50

可以看到我们建立了一个文件,然后查脚本中事件信息输出的日志,你会发现有一个事件发生了。

下面我们结合rsync来完整的写一个监控脚本。

网上有一篇文章写的不错,我这里把链接放过来,我是在他的脚本基础上做了一点修改,我也测试过不按照他那么写是否可行结果失败了,这个就跟rsync的同步机制有关。

原文出处真正的inotify+rsync实时同步 彻底告别同步慢

#/bin/bash
#运行此脚本的时候服务器列表文件要输入绝对路径,否则后面切换路径后会找到该文件。

#该参数是服务器IP列表文件
SERVER_LIST=$1

#源目录
SRC_DIR=/tmp/data
#目标目录
DES_DIR=backup
#目标服务器上的用于备份的目录,该目录用于备份更新时出现同名文件的时候
BACKUP_DIR=/backup/aaa
#连接服务器使用的用户名
USER=rsync_backup
#密码文件
PASSWD_FILE=/etc/rsyncd.passwd

if[!-n"$SERVER_LIST"];then
echo"请传递服务器IP列表文件,要用绝对路径。"
exit5
else
if[-d$SRC_DIR]&&[-e$PASSWD_FILE];then
echo"必要文件检查通过......"
else
echo"检查源路径或者密码文件失败,脚本无法执行,请检查。"
exit5
fi
fi

#切换到源目录
cd$SRC_DIR

inotifywait-mrq--timefmt'%y-%m-%d%H:%M'--format'%T%w%f%e'-emodify,delete,attrib,close_write,move./|whilereadfile
do
INFO_EVENT=$(echo$file|awk'{print$5}')
INFO_PATH=$(echo$file|awk'{print$5}')
echo"-------------------------------$(date)------------------------------------"
echo$file
forlinein$(cat$SERVER_LIST);do
#文件建立、修改、移出事件
if[[$INFO_EVENT=~'CREATE']]||[[$INFO_EVENT=~'MODIFY']]||[[$INFO_EVENT=~'CLOSE_WRITE']]||[[$INFO_EVENT=~'MOVED_TO']];then
rsync-avzcR--password-file=$PASSWD_FILE$(dirname${INFO_PATH})$USER@$line::$DES_DIR
fi
#删除、移动出事件
if[[$INFO_EVENT=~'DELETE']]||[[$INFO_EVENT=~'MOVED_FROM']];then
rsync-avzR--delete--password-file=$PASSWD_FILE$(dirname${INFO_PATH})$USER@$line::$DES_DIR
fi
#修改属性事件
if[[$INFO_EVENT=~'ATTRIB']];then
if[!-d"$INFO_FILE"];then
rsync-avzcR--password-file=$PASSWD_FILE$(dirname${INFO_PATH})$USER@$line::$DES_DIR
fi
fi
done
done

服务器列表文件

wKiom1gqgzWjYjH2AAA88z6X-NY149.jpg-wh_50

上面的代码文字比较中用了

[[VARIABLES=~VALUE]]

用=~这种操作符支持SHELL的正则表达式,在字符串比较的时候右边可以是一个模式而不一定是字符串。也就是变量内容包括VALUE的内容,那么就匹配模式。不过在这种形式下必须使用双中括号

在Inotify事件中有CREATE事件和CREATE.ISDIR事件,如果你使用=~那么就都会匹配。另外在IF多条件判断的时候,建议都使用独立的双中括号,这样可以避免逻辑错误


include和exclude的精确匹配:

我在工作中遇到一个问题,服务器(Windows服务器)上有几十个文件夹,需要把其中几个同步到文件服务器上,同时这些文件夹中有log目录,里面存放日志,我们不需要备份日志,只需要把指定文件夹中的除log目录的其他文件备份。

目录结构如下(我只是模拟了目录结构,并不是实际公司环境目录):

wKioL1hJctvwJplPAABomZfl0EU109.jpg-wh_50

要求是把Folder_A、B、E进行备份,同时它们里面的log_folder不备份。

rsync--port=28950-avz--progressadmin@192.168.100.10::Services/backup/Service--password-file=/etc/rsyncd.passwd--include-file=./includeFile--exclude-file=./excludeFile

意思是使用28950端口连接服务器,使用递归并保留权限,同时显示过程,备份100.10服务器中rsyncServer配置文件中[Services]段PATH指定的目录到本地/backup/Services目录中,使用密码文件为rsyncd.passwd,使用了包含文件为includeFile,排除文件为excludeFile


includeFile

Folder_A
Folder_B
Folder_E

excludeFile

log
Folder_C
Folder_D

说明:你想排除哪些文件或者目录就只用--exclude-from就行,但是如果说只想包含哪些文件的话你单独使用--include-from是不行的,必须用--exclude-from进行排除。


如果rsyncServer服务器是Windows的话,就要这样写路径

rsync--port28950-avz--progressadmin@192.168.100.20::test/cygdrive/d/rsyncscripts/test/backup--password-file=rsyncPwd.txt--include-from=includeFile.txt--exclude-from=excludeFile.txt

/cygdirve/d/rsyncscripts/test/backup 等于 d:/rsyncscripts/test/back


特别注意:

另外如果服务器上有中文目录的话,首先保存文件列表的文件要是UTF-8格式,同时文件的写法也要注意:文件第一行不要写真实目录名或者文件名,你随便写一些字母即可,从第二行开始写真实的文件名称或者目录名。

xxxxxxxxxxxxxx
文件1
文件2
目录1
目录2
File1
Folder1

我不知道为什么,反正我的环境中rsyncServer安装在一台Windows上,然后另外台Windows安装rsync客户端,从客户端上同步,因为包含一些中文名的目录,所以出了很多问题如果你的include文件和exclude文件第一个不加任意字符,那么同步过来的文件或者目录就会少。如果你的目录都是英文的则不需要这样操作。目录中的子目录或者文件如果有中文也无需在第一行添加任意字符。

猜你在找的CentOS相关文章