设为首页 收藏本站
查看: 1320|回复: 0

[经验分享] CentOS 6.5 inotify+rsync 部署

[复制链接]

尚未签到

发表于 2018-4-24 11:25:55 | 显示全部楼层 |阅读模式
  Rsync是一款远程同步软件,在同步文件(文件和目录)的时候可以保持原文件的权限、修改时间、包括链接文件也可以同步。
  这个东西应用在什么地方呢?不管你是什么业务,如果你有几十台以上的服务器,并且这些服务器需要实时保持拥有的文件一致,那你就会用到这个工具。比如你有几十台web服务器,网页文件会经常修改,如何批量同步这些新的网页文件到所有服务器上呢?
  

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

  
主机名IP说明
Linux01.localhost
10.10.6.12
推送文件
Linux02.localhost10.10.6.15
运行rsync守护进程,作为Server端,接收推送。
  说明:这个模式你要了解,不是服务器端向客户端推送数据,是客户端其实就是使用rsync工具向运行rsync服务的服务器端推送数据。所以一般运行的Web服务器上都安装此服务,用于接收页面文件的更新。
  

  安装Rsync
  实现原理:
  rsync采用的是C/S结构,不过S端是服务器端,运行rsync的守护进程,C端通过命令来向S端推送文件。
  安装:
rpm -qa rsync    #检查是安装了rsync
rpm -e rsync     #如果安装了,那么就删除,系统自带的版本比较低
wget https://download.samba.org/pub/rsync/rsync-3.1.2.tar.gz --no-check-certificate
DSC0000.jpg

DSC0001.jpg

tar -xzf rsync-3.1.2.tar.gz
cd rsync-3.1.2
./configure --prefix=/usr/local/rsync --disable-ipv6
DSC0002.jpg

DSC0003.jpg

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

make && make install  设置账户和目录:
groupadd -r rsync                         #创建rsync系统组
useradd -g rsync rsync -r -s /sbin/login  #创建rsync系统账号并加入到rsync组   DSC0005.jpg
mkdir backup                #创建用于接收推送文件的目录
chown rsync.rsync ./backup  #设置改目录的属主和属组位rsync   DSC0006.jpg
  编辑配置文件:编译安装后它使用的配置文件默认位置为/etc/rsyncd.conf,但是默认这个文件并不存在,需要你手动建立。
touch /etc/rsyncd.conf    #守护进程使用的配置文件,必须是rsyncd.conf
touch /etc/rsyncd.passwd  #用户名和密码文件,这个名字可以随便
chmod 600 /etc/rsyncd.passwd #修改密码文件权限   DSC0007.jpg
vim /etc/rsyncd.conf   #编辑配置文件#[全局配置]
# 服务器IP和监听端口号
address = 10.10.6.15
port = 873
# 服务器传输文件时服务器用哪个属主和属组去保存接收到的文件,也就是权限替换,如果在这里设
# 置成root,则会保留权限。
uid = root
gid = root
# 在文件传输之前,服务器守护进程将chroot到指定的PATH,优点是实时特殊的保护,缺点是需要roo# t权限
use chroot = no
# 最大并发数
max connection = 10
# 超时时长
timeout = 300
# 锁、日志和pid文件位置
lock file = /var/run/rsync.lock
log file = /var/run/rsync.log
pid file = /var/run/rsync.pid
# 消息文件,当客户端连接到服务器是该文件的内容将会显示给客户端,这个文件不是必须的
motd file = /etc/rsyncd.mod
# 存放虚拟用户和密码的文件
secrets file = /etc/rsyncd.passwd
# 允许的网段
hosts allow = *
# 不允许的网段
#hosts deny = 0.0.0.0/32
# 是否允许客户上传文件,true不允许,false允许。
read only = false
#[模块配置],所谓模块配置其实就是要使用的目录,客户端推送文件到服务器端的哪个目录
[backup]
# 需要接收同步的目录
path = /usr/local/backup
# 是否忽略错误
ignore errors
list = false
# 虚拟的用户,也就是客户端用那个用户来连接服务器,可以用空格或者逗号分隔多个用户,该用户
# 必须在上面secrets file = /etc/rsyncd.passwd文件中
auth users = rsync_backup
# 该模块的描述,客户端连接后会显示给客户端
commment = hellovim /etc/rsyncd.passwd   #编辑密码文件  
   DSC0008.jpg
./rsync --daemon   #启动服务   DSC0009.jpg
  说明:rsync可以以守护进程的方式运行,也可以由xinetd来激活,如果你的服务器负载比较高建议rsync以独立的守护进程方式来运行。区别在于,如果以独立的守护进程方式运行,它会一直监听端口随时准备接受文件推送,如果由xinetd这个超级进程来管理的话,那没有推送的时候rsync是休眠状态,当有推送的时候,由xinetd这个超级进程激活rsync,对于繁忙的服务器来说这种方式会有额外开销。

  

  连接测试:
  在数据源服务器,这里的环境是Linux01,安装rsync。步骤同上。
touch /etc/rsyncd.passwd  #建立密码文件
echo "123456" > /etc/rsyncd.passwd   #这个文件仅存储密码,服务器端和用户名对应的密码
chmod 600 /etc/rsyncd.passwd  #修改权限   DSC00010.jpg
参数说明
-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使用非标准端口,那么你在用客户端连接的时候就要指定端口
  发送文件
DSC00011.jpg

  查看接收到的文件
DSC00012.jpg

  有没有注意到权限问题?发送文件的时候hello的属主和属组是chen,但是发送过去以后就变成rsync了。因为我们知道-a参数的含义是保留权限、属主和属组,那为什么传递过去之后就变了呢?
  原因就在于配置文件里面的uid和gid设置,看下图:
DSC00013.jpg

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

DSC00015.jpg

  你会发现权限一样、时间一样、属主和属组也一样。
  注意:前提也得是你服务器端有这个同名账户才行,如果没有,这里你查看到的就仅仅是一串数字,也就是权限信息。

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

  下图是在Linux02上也就是rsync服务器端看到的hello文件内容
   DSC00017.jpg
  在Linux01上执行命令
rsync -avz -b --backup-dir=/aaa hello --progress rsync_backup@10.10.6.15::backup --password-file=/etc/rsyncd.passwd  如果要同步目录的话,就把上面的hello文件换成目录
DSC00018.jpg

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

  因为我们加了一个-d的参数,这个参数就是对同名文件更新前先备份,备份到--backup-dir=指定目录,如果没有就新建一个。
  现在我们说一下如何关闭rsync进程,它如果作为守护进程来运行的话,你得手动KILL掉进程,然后删除PID文件才行。为了方便我们写一个脚本来执行上述操作
#/bin/bash
#
#该脚本的执行前提是你的rsync服务端配置文件要是/etc/rsyncd.conf,如果不是,请替换成实际位
#置
#从配置文件中获取PID文件位置
PIDFILE=`cat /etc/rsyncd.conf | grep 'pid file' | awk -F' ' '{print $4}'`
#echo $PIDFILE
#判断该文件是否存在
if [ -e $PIDFILE ]; then
  cat $PIDFILE | xargs kill -9
  rm -rf $PIDFILE
  echo "rsync服务已经关闭。"
else
  echo "当前系统没有运行rsync服务。"
fi  我们知道通过这个rsync是为了实现批量同步,但是我们发现同步命令一次指定同步一台主机,如何做到批量同步多台主机呢?rsync本身没有这个功能,需要自己写脚本实现:
  首先准备一个服务器IP列表的文件,文件格式如下:
   DSC00020.jpg
  其次写一个执行批量同步的脚本,并且能区分是删除还是其他更新操作
#/bin/bash
#
#该参数是服务器IP列表文件
SERVERLIST=$1
#源目录
SRC_DIR=data
#目标目录
DES_DIR=backup
#目标服务器上的用于备份的目录,该目录用于备份更新时出现同名文件的时候
BACKUP_DIR=/backup/aaa
#连接服务器使用的用户名
USER=rsync_backup

#判断文件是否存在
if [ -e $1 ]; then
  #读取逐行读取文件
  for line in $(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
DSC00021.jpg

  对rsync各种参数的测试,我看到的也是别人转的,所以把链接贴在这里 rsync深入分析
  上面都是基于手动运行脚本或命令来进行同步的,那能否自动化执行呢?简单的办法是就是把命令或脚本加入到计划任务重crontab,或者使用inotify,我们推荐使用inotity,因为它不是单一定期的执行推送,关键它可以变化。

  

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

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

  •   inotifywait:监控文件或目录变化
  •   inotifywatch:统计文件系统访问的次数
wget  --no-check-certificate
如果遇到SSL无法连接之类的,请升级wgettar -zxf inotify-tools-3.14.tar.gz
cd inotifi-tools-3.14
/configure --prefix=/usr/local/inotify
make && make install  inotifywait命令参数:
参数说明
--fromfile从文件读取需要监视或者排除的文件或目录,一个文件一行,排除的文件以@开头
-m针对事件持续监听,如果不加该参数那么获取一次事件后就退出了。
-d运行在后台
-r递归监控目录
-o输出事件到文件中,而不是输出到STDOUT
-s输出错误到系统日志中,而不是输出到STEDRR
-q除了输出事件之外,不显示其他信息
-t超时时间
--format  设置事件输出格式
  %w  表示发生事件的目录
  %f   表示发生事件的文件
  %e   所发生的事件
  %Xe  事件以X分隔
  %T  使用由-timefmt定义的时间格式
--timefmt  指定时间输出格式,用于-fromat选项中的%T格式
  %y-%m-%d %H:%M
-excludei排除文件或目录,不区分大小写
-e -event
  如果使用该参数,你就需要手动指定要监控的事件,多个事件用逗号分隔

  •   access  读取文件或目录内容
  •   modify  修改文件或目录内容
  •   move     移动文件或目录
  •   create    建立文件或目录
  •   delete    删除文件或目录
  •   attrib     修改文件或目录属性
  •   close_write    修改真实的文件内容
  •   close_nowrite
  •   close
  •   open  文件或目录被打开
  •   move-to  移动文件或目录到哪
  •   move-from   从哪移动文件或目录
  •   umount   卸载文件系统
  inotifywatch命令参数:
参数说明
-fromfile从文件读取需要监视或者排除的文件或目录,一个文件一行,排除的文件以@开头
-z输出表格的行和列
-excludei同上
-e设置指定的监听事件,具体事件同上
-r递归监视
-a
以指定事件的升序排列
-d
以指定事件的降序排列
  要实现监控,并且捕捉文件变化,然后根据变化来进行同步,这里主要是思路问题:

  •   首先我们要把对文件或者目录的操作分成2大类,一是删除和移动、二是其他(包括建立、修改),因为这两类不同操作对于要执行的rsync语句所带的参数不同
  •   其次要通过inotifywait来监控指定的目录,并获取那些文件或目录发生了哪些变化
  •   最后根据这些捕捉的变化来执行rsync语句
  我们这里先测试一下inotifywait的效果,为了让inotifywait可以直接执行请修改环境变量。

  监控脚本
#/bin/bash
#
inotifywait -mrq -e modify,create,move,delete --fromfile '/tmp/filelist' --timefmt '%y-%m-%d %H:%M' --format '%T %w %f %e' --outfile '/tmp/i.log'  要监控的目录列表文件
DSC00023.jpg

  测试,这个脚本目前是在前台运行,所以是这种状况,你也可以设置为后台运行,只要在脚本后面加一个 &,然后exit正常退出终端,那么脚本就可以很好的后台继续运行,如果你直接关闭窗口的话,脚本会中断。
DSC00024.jpg

DSC00025.jpg

  可以看到我们建立了一个文件,然后查脚本中事件信息输出的日志,你会发现有一个事件发生了。
  下面我们结合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列表文件,要用绝对路径。"
  exit 5
else
  if [ -d $SRC_DIR ] && [ -e $PASSWD_FILE ]; then
    echo "必要文件检查通过......"
  else
    echo "检查源路径或者密码文件失败,脚本无法执行,请检查。"
    exit 5
  fi
fi
#切换到源目录
cd $SRC_DIR         
inotifywait -mrq --timefmt '%y-%m-%d %H:%M' --format  '%T %w %f %e' -e modify,create,delete,attrib,close_write,move ./ | while read file
do
  INFO_EVENT=$(echo $file | awk '{print $5}')      
  INFO_PATH=$(echo $file | awk '{print $5}')   
  echo "-------------------------------$(date)------------------------------------"
  echo $file
  for line in $(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  服务器列表文件

DSC00026.jpg

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

[[ VARIABLES =~ VALUE ]]  用=~这种操作符支持SHELL的正则表达式,在字符串比较的时候右边可以是一个模式而不一定是字符串。也就是变量内容中包括VALUE的内容,那么就匹配模式。不过在这种形式下必须使用双中括号。
  在Inotify事件中有CREATE事件和CREATE.ISDIR事件,如果你使用=~那么就都会匹配。另外在IF多条件判断的时候,建议都使用独立的双中括号,这样可以避免逻辑错误。

  

  include和exclude的精确匹配:
  我在工作中遇到一个问题,服务器(Windows服务器)上有几十个文件夹,需要把其中几个同步到文件服务器上,同时这些文件夹中有log目录,里面存放日志,我们不需要备份日志,只需要把指定文件夹中的除log目录的其他文件备份。
  目录结构如下(我只是模拟了目录结构,并不是实际公司环境目录):
DSC00027.jpg

  要求是把Folder_A、B、E进行备份,同时它们里面的log_folder不备份。
rsync --port=28950 -avz --progress admin@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 --port 28950 -avz --progress admin@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文件第一个不加任意字符,那么同步过来的文件或者目录就会少。如果你的目录都是英文的则不需要这样操作。目录中的子目录或者文件如果有中文也无需在第一行添加任意字符。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-451345-1-1.html 上篇帖子: Centos6.5安装jmeter压力测试工具 下篇帖子: centos mogodb 安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表