利用Inotify和Rsync將web工程檔案自動同步到多臺應用伺服器

mchdba發表於2014-06-29


背景:需要搭建一套跟線上一模一樣的環境,用來預釋出,這是其中的web分發的一個小模組的實現過程。

 

1 工具以及環境簡介

1.1Inotify工具

Inotify,它是一個核心用於通知使用者空間程式檔案系統變化的機制。眾所周知,Linux 桌面系統與 MAC Windows 相比有許多不如人意的地方,為了改善這種狀況,開源社群提出使用者態需要核心提供一些機制,以便使用者態能夠及時地得知核心或底層硬體裝置發生了什麼,從而能夠更好地管理裝置,給使用者提供更好的服務,如 hotplugudev inotify 就是這種需求催生的。Hotplug 是一種核心向使用者態應用通報關於熱插拔裝置一些事件發生的機制,桌面系統能夠利用它對裝置進行有效的管理,udev 動態地維護 /dev 下的裝置檔案,inotify 是一種檔案系統的變化通知機制,如檔案增加、刪除等事件可以立刻讓使用者態得知,該機制是著名的桌面搜尋引擎專案 beagle 引入的,並在 Gamin 等專案中被應用。

 

1.2rsync工具

它是類unix系統下的資料映象備份工具,實現遠端同步remote sync,它的特性如下:

(1),可以映象儲存整個目錄樹和檔案系統。

(2),可以很容易做到保持原來檔案的許可權、時間、軟硬連結等等。

(3),無須特殊許可權即可安裝。

(4),快速:第一次同步時 rsync 會複製全部內容,但在下一次只傳輸修改過的檔案。rsync 在傳輸資料的過程中可以實行壓縮及解壓縮操作,因此可以使用更少的頻寬。

(5),安全:可以使用scpssh等方式來傳輸檔案,當然也可以透過直接的socket連線。

(6),支援匿名傳輸,以方便進行網站鏡象。

 

1.3,簡單環境介紹:

(1),伺服器端(程式碼釋出伺服器):192.168.0.51

(2),客戶端(Web伺服器):192.168.0.50,192.168.0.53

(3)Web目錄:/usr/local/nginx/web/

(4),基本原理:由192.168.0.51inotify服務監測檔案目錄/usr/local/nginx/web是否有更新,如果有更新(修改,刪除,新建)inotify就會透過rsync命令將更新的檔案推向二臺web伺服器(192.168.0.50192.168.0.53)

(5),架構圖如下:

2.1,檢視線上inotify版本

透過rsync -h找到檢視幫助,找到 --version引數。

[root@localhost bin]# inotifywait --help

inotifywait 3.14

Wait for a particular event on a file or set of files.

Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]

Options:

……

 看到版本號碼是3.14

 

2.2,下載inotify版本

下載地址:

 

2.3,開始編譯安裝

[root@localhost root] tar -xvf inotify-tools-3.14.tar.gz

透過./configure --help檢視編譯引數,這裡選取--prefix引數,開始編譯:

[root@localhost inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify-tools-3.14

...

config.status: creating Makefile

config.status: creating src/Makefile

config.status: creating man/Makefile

config.status: creating libinotifytools/Makefile

config.status: creating libinotifytools/src/Makefile

config.status: creating libinotifytools/src/inotifytools/Makefile

config.status: creating config.h

config.status: creating libinotifytools/src/inotifytools/inotify.h

config.status: executing depfiles commands

config.status: executing libtool commands

 

[root@localhost inotify-tools-3.14]# time make

...

fytools.so -Wl,-rpath -Wl,/usr/local/inotify-tools-3.14/lib

make[2]: Leaving directory `/root/inotify-tools-3.14/src'

Making all in man

make[2]: Entering directory `/root/inotify-tools-3.14/man'

make[3]: Entering directory `/root/inotify-tools-3.14'

make[3]: Leaving directory `/root/inotify-tools-3.14'

make[2]: Nothing to be done for `all'.

make[2]: Leaving directory `/root/inotify-tools-3.14/man'

make[2]: Entering directory `/root/inotify-tools-3.14'

cd . && /bin/sh ./config.status config.h

config.status: creating config.h

config.status: config.h is unchanged

make[2]: Leaving directory `/root/inotify-tools-3.14'

make[1]: Leaving directory `/root/inotify-tools-3.14'

 

real  0m2.889s

user 0m1.768s

sys   0m0.589s

 

[root@localhost inotify-tools-3.14]# time make install

...

make[2]: Nothing to be done for `install-exec-am'.

make[2]: Nothing to be done for `install-data-am'.

make[2]: Leaving directory `/root/inotify-tools-3.14'

make[1]: Leaving directory `/root/inotify-tools-3.14'

 

real  0m0.854s

user 0m0.454s

sys   0m0.254s

 

2.4,做成軟連線到/usr/lib

ln -sv /usr/local/inotify-tools-3.14/lib/libinotify* /usr/lib/ 

ln -s /usr/local/inotify-tools-3.14/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0

設定環境變數:

[root@localhost ~]# echo "export PATH=$PATH:/usr/local/inotify-tools-3.14/bin">>/etc/profile

[root@localhost ~]# source /etc/profile

[root@localhost ~]# inotifywait --help

inotifywait 3.14

Wait for a particular event on a file or set of files.

Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]

...

現在可以直接用inotify命令而不用附帶加上全路徑

 

3,開始安裝rsync軟體

192.168.0.51192.168.0.50192.168.0.53按照如下順序安裝rsync軟體

3.1,檢視線上rsync版本

透過rsync -h找到檢視幫助,找到 --version引數。

[root@localhost ~]# rsync --version

rsync  version 3.0.6  protocol version 30

Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others.

Web site:

[root@localhost ~]#

 

3.2,下載

wget

 

3.3,編譯安裝

# 解壓縮

[root@localhost root]# tar -xvf rsync-3.0.6.tar.gz

[root@localhost rsync-3.0.6]# cd rsync-3.0.6

# 透過./configure --help檢視編譯引數,這裡選取--prefix引數

[root@localhost rsync-3.0.6]# ./configure --prefix=/usr/local/rsync-3.0.6/

......

config.status: creating lib/dummy

config.status: creating zlib/dummy

config.status: creating popt/dummy

config.status: creating shconfig

config.status: creating config.h

 

    rsync 3.0.6 configuration successful

 

[root@localhost rsync-3.0.6]# make

......

gcc -std=gnu99 -I. -I. -g -O2 -DHAVE_CONFIG_H -Wall -W -I./popt  -c popt/poptparse.c -o popt/poptparse.o

gcc -std=gnu99 -g -O2 -DHAVE_CONFIG_H -Wall -W -I./popt  -o rsync flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o progress.o pipe.o params.o loadparm.o clientserver.o access.o connection.o authenticate.o lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o  zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o popt/findme.o  popt/popt.o  popt/poptconfig.o popt/popthelp.o popt/poptparse.o

[root@localhost rsync-3.0.6]#

[root@localhost rsync-3.0.6]# make install

mkdir -p /usr/local/rsync-3.0.6/bin

/usr/bin/install -c  -m 755 rsync /usr/local/rsync-3.0.6/bin

mkdir -p /usr/local/rsync-3.0.6/share/man/man1

mkdir -p /usr/local/rsync-3.0.6/share/man/man5

if test -f rsync.1; then /usr/bin/install -c -m 644 rsync.1 /usr/local/rsync-3.0.6/share/man/man1; fi

if test -f rsyncd.conf.5; then /usr/bin/install -c -m 644 rsyncd.conf.5 /usr/local/rsync-3.0.6/share/man/man5; fi

[root@localhost rsync-3.0.6]#

 

3.3check命令

[root@localhost ~]# rsync -h

rsync  version 3.0.6  protocol version 30

Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others.

Web site:

看來已經安裝好,命令可以直接使用。

 

3.4,配置rsyncd.conf啟動引數檔案

[root@localhost ~]# vim /etc/rsyncd.conf

uid=nginx  #使用者id名稱

gid=nginx  #使用者所屬組ID

use chroot=no

max connections=10

strict modes=yes

port=873

address=192.168.0.50 #本機地址,3臺IP地址都填寫自己的IP地址

#ignore erros

read only=no

list=no

auth users=nginx

secrets file=/etc/rsync.pas  #密碼認證檔案地址

hosts allow=192.168.0.51,192.168.0.53 #允許rsync同步的ip地址,除了本機地址的其它2個ip地址。

pid file=/home/nginx/rsync/rsyncd.pid

lock file=/home/nginx/rsync/rsync.lock

log file=/home/nginx/rsync/rsyncd.log

 

[web]

path=/usr/local/nginx/ # 這裡的web就是rsync同步的引數名字,path就是同步的目錄

comment=mirror for web

 

3.5,新增認證檔案

# 建立認證檔案

[root@localhost ~]# vim /etc/rsync.pas

nginxpasspd #密碼

 nginx:nginxpasswd #使用者名稱:密碼

PS】:不這樣設定兩行就會使用者驗證失敗。

 # 賦予許可權

[root@localhost ~]# chmod 600 /etc/rsync.pas

 

3.6,建立目錄並賦予許可權

# 建立目錄

mkdir -p /usr/local/nginx

mkdir -p /home/nginx/rsync

mkdir -p /usr/local/nginx/web

# 賦予許可權

chown -R nginx.nginx  /usr/local/nginx /home/nginx/rsync/ /usr/local/nginx/web

 

3.7,啟動rsync服務

[root@localhost ~]# rsync --daemon --config=/etc/rsyncd.conf

[root@localhost ~]# ps -eaf|grep rsync

root      1387     1  0 Jun28 ?        00:00:00 rsync --daemon --config=/etc/rsyncd.conf

root      3201  3136  0 00:50 pts/0    00:00:00 grep rsync

[root@localhost ~]#

啟動成功

 

3.8,測試rsync功能

一些除錯報錯經歷:

[root@localhost ]#

rsync -vzrt --delete --progress --itemize-changes --exclude-from=/home/nginx/exclude_fastdfs.txt /data/fastdfs/data nginx@192.168.0.53::web --password-file=/etc/rsync.pas

password file must not be other-accessible

continuing without password file

Password:

@ERROR: auth failed on module web

rsync error: error starting client-server protocol (code 5) at main.c(1503) [sender=3.0.6]

[root@localhost ]#

說明:這是因為/etc/rsync.pas的許可權不對,應該設定為600。如:chmod 600 /etc/rsync.pas

 

[root@localhost inotify-tools-3.14]#

rsync -vzrt --delete --progress --itemize-changes --exclude-from=/home/nginx/exclude_fastdfs.txt /data/fastdfs/data nginx@192.168.0.53::fastdfs --password-file=/home/nginx/rsync.pas

@ERROR: auth failed on module fastdfs

rsync error: error starting client-server protocol (code 5) at main.c(1503) [sender=3.0.6]

[root@localhost inotify-tools-3.14]# ll

去檢視192.168.0.53的log資訊

[root@localhost inotify-tools-3.14]# tail -f /home/nginx/rsync/rsyncd.log

2014/06/28 17:24:14 [19031] auth failed on module web from unknown (192.168.0.50): missing secret for user "nginx"

2014/06/28 17:28:21 [19198] name lookup failed for 192.168.0.50: Name or service not known

2014/06/28 17:28:21 [19198] connect from UNKNOWN (192.168.0.50)

2014/06/28 17:28:21 [19198] auth failed on module web from unknown (192.168.0.50): missing secret for user "nginx"

2014/06/28 17:28:48 [19488] name lookup failed for 192.168.0.50: Name or service not known

去192.168.0.53上面修改認證檔案

[root@localhost data]# vim /etc/rsync.pas

nginxpasswd

nginx: nginxpasswd

將原來只有一行密碼的改成如此2行,就好使了,能使用rsync功能了。

測試驗證,在192.168.0.50的空目錄下,建立測試檔案 1.txt2.txt

[root@localhost data]# cd /usr/local/nginx/web

[root@localhost web]# ll

總用量 0

[root@localhost web]# vim 1.txt

[root@localhost web]# vim 2.txt

[root@localhost web]# mkdir test

[root@localhost web]# vim ./test/3.txt

[root@localhost web]# ll /usr/local/nginx/web

總用量 12

-rw-r--r--. 1 nginx nginx    6 6  28 19:18 1.txt

-rw-r--r--. 1 nginx nginx    6 6  28 19:18 2.txt

drwxr-xr-x. 2 nginx nginx 4096 6  28 19:22 test

[root@localhost web]#

 

rsync同步之前,先去53上面check下目標目錄,為空目錄,如下所示:

[root@localhost web]# ll /usr/local/nginx/web

總用量 0

[root@localhost web]#

 

在192.168.0.50上執行rsync命令,同步目錄

[root@localhost web]# /usr/bin/rsync -auzv --progress --delete /usr/local/nginx/web nginx@192.168.0.53::webroot   --password-file=/etc/rsync.pas

sending incremental file list

web/

web/1.txt

           6 100%    0.00kB/s    0:00:00 (xfer#1, to-check=3/5)

web/2.txt

           6 100%    5.86kB/s    0:00:00 (xfer#2, to-check=2/5)

web/test/

web/test/3.txt

           3 100%    2.93kB/s    0:00:00 (xfer#3, to-check=0/5)

sent 264 bytes  received 73 bytes  224.67 bytes/sec

total size is 15  speedup is 0.04

[root@localhost web]#

 

再去192.168.0.53上check下,看到檔案已經同步過來,測試成功,如下所示:

[root@localhost web]# ll

總用量 12

-rw-r--r--. 1 nginx nginx    6 6  28 19:18 1.txt

-rw-r--r--. 1 nginx nginx    6 6  28 19:18 2.txt

drwxr-xr-x. 2 nginx nginx 4096 6  28 19:22 test

[root@localhost web]#

 

4,使用Inotify結合rsync來進行隨時隨地自動釋出web工程

編寫一個inotify使用案例指令碼inotify_web.sh:

4.1 inotify_web指令碼

[root@localhost inotify-tools-3.14]# vim /usr/local/inotify-tools-3.14/inotify_web.sh

#!/bin/bash

src=/usr/local/nginx/web

des=web

#ip1=192.168.0.50ip2是另外一臺伺服器ip地址

host="192.168.0.50 192.168.0.53"

# 使用inotifywait隨時監控$src目錄的一切變更,如果有,就自動呼叫後面的do…done裡面的rsync程式碼塊,將一切變更同步到兩臺web伺服器上相同的目錄裡面。

/usr/local/inotify-tools-3.14/bin/inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T%w%f' -e close_write,move,delete,create $src | while read files

do

  for hostip in $host

         do

                       echo "`date '+%F %T'` start to resync $src to $hostip"

                       /usr/bin/rsync -auzv --progress --delete $src nginx@$hostip::$des --password-file=/etc/rsync.pas

                   echo "$src has been resynced to $hostip `date '+%F %T'`"

         done

    echo "${files} was rsynced" >>/tmp/rsync.log 2>&1

done

 

4.2,設定後臺啟動任務

[root@localhost inotify-tools-3.14]#

# 啟動

nohup sh /usr/local/inotify-tools-3.14/inotify_web.sh >/tmp/inotify_rsync.log 2>&1 &

# 可以/tmp/inotify_rsync.log隨時檢視執行的日誌資訊

 

4.3,啟動後,檢視後臺執行的程式:

[root@localhost inotify-tools-3.14]# ps -eaf|grep ino

root     17842 17594  0 20:15 pts/1    00:00:00 sh /usr/local/inotify-tools-3.14/inotify_web.sh

root     17843 17842  0 20:15 pts/1    00:00:00 /usr/local/inotify-tools-3.14/bin/inotifywait -mrq --timefmt %d/%m/%y/%H:%M --format %T%w%f -e close_write,move,delete,create /usr/local/nginx/web

root     17844 17842  0 20:15 pts/1    00:00:00 sh /usr/local/inotify-tools-3.14/inotify_web.sh

root     17872 17594  0 20:16 pts/1    00:00:00 tail -f /tmp/inotify_rsync.log

nginx    17882 17848  0 20:18 pts/0    00:00:00 grep ino

 

4.4,測試,check結果:

  清空192.168.0.50192.168.0.53上面的/usr/local/nginx/web下面所有檔案,然後在inotify監聽伺服器上的/usr/local/nginx/web建立wb.txt

按照原理,一旦在inotify建立了檔案,那麼就會把/usr/local/nginx/web下面的所有檔案同步到192.168.0.50192.168.0.53的相應/usr/local/nginx/web目錄下面。

(1),去檢視inotify任務日誌資訊

[root@localhost web]# tail -f /tmp/inotify_rsync.log

nohup: 忽略輸入

2014-06-28 20:16:20 start to resync /usr/local/nginx/web to 192.168.0.50

sending incremental file list

web/

web/dd.txt

           0 100%    0.00kB/s    0:00:00 (xfer#1, to-check=4/6)

web/i3.txt/

web/t.txt/

 

sent 193 bytes  received 40 bytes  466.00 bytes/sec

total size is 6  speedup is 0.03

/usr/local/nginx/web has been resynced to 192.168.0.50 2014-06-28 20:16:20

2014-06-28 20:16:20 start to resync /usr/local/nginx/web to 192.168.0.53

sending incremental file list

web/

web/dd.txt

           0 100%    0.00kB/s    0:00:00 (xfer#1, to-check=4/6)

web/wb.txt

           6 100%    0.00kB/s    0:00:00 (xfer#2, to-check=3/6)

web/i3.txt/

web/t.txt/

web/test/

 

sent 242 bytes  received 62 bytes  608.00 bytes/sec

total size is 6  speedup is 0.02

/usr/local/nginx/web has been resynced to 192.168.0.53 2014-06-28 20:16:20

 

(2),去另外一臺192.168.0.53,檢視下,檔案已經同步過去。

[root@localhost web]# pwd

/usr/local/nginx/web

[root@localhost web]# ll

總用量 16

-rw-r--r--. 1 nginx nginx    0 6  28 20:04 dd.txt

drwxrwxr-x. 2 nginx nginx 4096 6  28 20:16 i3.txt

drwxr-xr-x. 2 nginx nginx 4096 6  28 19:53 test

drwxr-xr-x. 2 nginx nginx 4096 6  28 20:10 t.txt

-rw-r--r--. 1 nginx nginx    6 6 28 19:51 wb.txt

 

至此,簡單的透過inotifyrsync實現web工程自動同步功能已經完成,還有一點小細節留待後續解決。

 

參考文獻:

http://zhumeng8337797.blog.163.com/blog/static/100768914201172952619883/

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26230597/viewspace-1198191/,如需轉載,請註明出處,否則將追究法律責任。

相關文章