Sersync实现触发式文件同步
序 言:如果我們后端有多臺網(wǎng)站服務(wù)器或者文件服務(wù)器,而且沒有好的文件同步機(jī)制,那么當(dāng)我們升級程序或者更新文件的時候,就需要每臺服務(wù)器或者目錄都要更 新,這樣很容易出問題,并很容易導(dǎo)致兩邊的文件不一致,從而出現(xiàn)很多莫民其妙的問題。因此我們需要使用好的文件同步方式來實(shí)現(xiàn)幾個后端服務(wù)器文件的同步, 目前廣泛采用的方案是使用rsync+inotify的方式來實(shí)現(xiàn)文件的觸發(fā)更新。原理是采用inotify來對文件進(jìn)行監(jiān)控,當(dāng)監(jiān)控到文件有文件發(fā)生改變的時候,就會調(diào)用rsync實(shí)現(xiàn)觸發(fā)式實(shí)時同步!本文就來詳細(xì)介紹金山的一個居于inotify+rsync進(jìn)行二次開發(fā)實(shí)現(xiàn)文件同步的小工具sersync,能夠很方便的實(shí)現(xiàn)文件觸發(fā)式同步
inotify簡介
是基于inode級別的文件系統(tǒng)監(jiān)控技術(shù),是一種強(qiáng)大的、細(xì)粒度的、異步的機(jī)制,它滿足各種各樣的文件監(jiān)控需要,不僅限于安全和性能,內(nèi)核要求2.6.13以上,inotify能監(jiān)控非常多的文件系統(tǒng)事件,通過監(jiān)控這些事件來監(jiān)控文件是否發(fā)生變更,然后通過rsync來更新發(fā)生變更的文件,Inotify 可以監(jiān)視的文件系統(tǒng)事件包括:
1?IN_ACCESS,即文件被訪問
2?IN_MODIFY,文件被write
3?IN_ATTRIB,文件屬性被修改,如chmod、chown、touch 等
4?IN_CLOSE_WRITE,可寫文件被close
5?IN_CLOSE_NOWRITE,不可寫文件被close
6?IN_OPEN,文件被open
7?IN_MOVED_FROM,文件被移走,如mv
8?IN_MOVED_TO,文件被移來,如mv、cp
9?IN_CREATE,創(chuàng)建新文件
10?IN_DELETE,文件被刪除,如rm
11?IN_DELETE_SELF,自刪除,即一個可執(zhí)行文件在執(zhí)行時刪除自己
12?IN_MOVE_SELF,自移動,即一個可執(zhí)行文件在執(zhí)行時移動自己
13?IN_UNMOUNT,宿主文件系統(tǒng)被umount
14?IN_CLOSE,文件被關(guān)閉,等同于(IN_CLOSE_WRITE |IN_CLOSE_NOWRITE)
15?IN_MOVE,文件被移動,等同于(IN_MOVED_FROM | IN_MOVED_TO)
備注:上面的文件也包括目錄。
Rsync簡介
?rsync,remote synchronize顧名思意就知道它是一款實(shí)現(xiàn)遠(yuǎn)程同步功能的軟件,它在同步文件的同時,可以保持原來文件的權(quán)限、時間、軟硬鏈接等附加信息。rsync是用?“rsync 算法”提供了一個客戶機(jī)和遠(yuǎn)程文件服務(wù)器的文件同步的快速方法,而且可以通過ssh方式來傳輸文件,這樣其保密性也非常好,另外它還是免費(fèi)的軟件。
rsync 包括如下的一些特性:
- 能更新整個目錄和樹和文件系統(tǒng);
- 有選擇性的保持符號鏈鏈、硬鏈接、文件屬于、權(quán)限、設(shè)備以及時間等;
- 對于安裝來說,無任何特殊權(quán)限要求;
- 對于多個文件來說,內(nèi)部流水線減少文件等待的延時;
- 能用rsh、ssh 或直接端口做為傳輸入端口;
- 支持匿名rsync 同步文件,是理想的鏡像工具;
sersync簡介
- 利用inotify與rsync對服務(wù)器進(jìn)行實(shí)時同步,其中inotify用于監(jiān)控文件系統(tǒng)事件,rsync是目前廣泛使用的同步算法,其優(yōu)點(diǎn)是只對文件不同的部分進(jìn)行操作,所以其優(yōu)勢大大超過使用掛接文件系統(tǒng)的方式進(jìn)行鏡像同步。由金山的周洋開發(fā)完成,是目前使用較多的文件同步工具之一。該工具和其他的工具相比有如下優(yōu)點(diǎn):
- sersync是使用c++編寫,由于只同步發(fā)生更改的文件,因此比其他同步工具更節(jié)約時間、帶寬;
- 安裝方便、配置簡單;
- 使用多線程進(jìn)行同步,能夠保證多個服務(wù)器實(shí)時保持同步狀態(tài);
- 自帶出錯處理機(jī)制,通過失敗隊列對出錯的文件重新出錯,如果仍舊失敗,則每10個小時對同步失敗的文件重新同步;
- 自帶crontab功能,只需在xml配置文件中開啟,即可按您的要求,隔一段時間整體同步一次;
- 自帶socket與http協(xié)議擴(kuò)展,你可以方便的進(jìn)行二次開發(fā);
sersync實(shí)現(xiàn)觸發(fā)式文件同步實(shí)戰(zhàn)
- 服務(wù)器文件同步圖
???從服務(wù)器的安裝配置
安裝rsync
yum -y install rsync
配置rsync
vim ?/etc/rsyncd.conf
# Rsync configuration file
uid = root
gid = root
port = 873
max connections = 20000
use chroot = yes
timeout = 200
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log format = %t %a %m %f %b
auth users = root
secrets file = /etc/rsyncd.secret
?
[test]
path = /data/wwwroot/
comment = "test directory file"
list = yes
read only = no
ignore errors = yes
hosts allow = 192.168.3.205
hosts deny = *
vim /etc/rsyncd.secret
root:abc123@#$
Chmod 600 /etc/rsyncd.secret
600權(quán)限,不然同步的時候會報password file must not be other-accessible錯誤
Rsync的啟動
啟動有兩種方式,兩種方式哪一種都可以,讀者可以自行選擇:
daemon的方式啟動:
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
?
xinetd集成啟動方式:
chkconfig rsync on
chkconfig xinetd on
/etc/init.d/xinetd start
驗(yàn)證rsync是否啟動
[root@test_machine test]# ps aux | grep rsync
root ????3275 ?0.0 ?0.0 65516 ??472 ? ???????Ss ?13:44 ??0:00 /usr/bin/rsync--daemon --config=/etc/rsyncd.conf
root ????3306 ?0.0 ?0.1 71812 ??936 ? ???????S ??14:49 ??0:00 /usr/bin/rsync--daemon --config=/etc/rsyncd.conf
[root@test_machine test]# netstat -lnp | grep?rsync
tcp ???????0 ?????0 0.0.0.0:873 ????????????????0.0.0.0:* ??????????????????LISTEN ?????3275/rsync ?????????
tcp ??????0 ?????0 :::873 ?????????????????????:::* ???????????????????????LISTEN ?????3275/rsync
主服務(wù)器的安裝配置
安裝rsync
yum -y install rsync
安裝sersync
wget ?http://sersync.googlecode.com/files/sersync2.5.4_64bit_binary_stable_final.tar.gz
tar xzvfsersync2.5_64bit_binary_stable_final.tar.gz
mv GNU-Linux-x86 /usr/local/sersync
配置sersync
<head version="2.5">
<host hostip="localhost" port="8008"></host>
???<debug start="false"/>
???<fileSystem xfs="false"/>
??<filter start="false">
?<exclude expression="(.*)\.svn"></exclude>
??<exclude expression="(.*)\.gz"></exclude>
??<exclude expression="^info/*"></exclude>
??</filter>
????<inotify>
??????<delete start="true"/>
??????<createFolder start="true"/>
??????<createFile start="true"/>
??????<closeWrite start="true"/>
??????<moveFrom start="true"/>
??????<moveTo start="true"/>
??????<attrib start="true"/>
??????<modify start="true"/>
</inotify>
?????<sersync>
?????<localpath watch="/data/test">
?<remote ip="192.168.3.203" name="test"/>
?</localpath>
??????<rsync>
???<commonParams params="-artuz"/>
??<auth start="true" users="root" passwordfile="/etc/rsyncd.secret"/>
??????<userDefinedPort start="true" port="873"/>
?????????<timeout start="false" time="100"/>
???????????<ssh start="false"/>
???????</rsync>
???????<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/>
???????<crontab start="false" schedule="600"><!--600mins-->
???????????<crontabfilter start="false">
????????????????<exclude expression="*.php"></exclude>
???????????????<exclude expression="info/*"></exclude>
????????????</crontabfilter>
????????</crontab>
????????<plugin start="false" name="command"/>
???????</sersync>
?
??<plugin name="command">
????????<param prefix="/bin/sh" suffix="" ignoreError="true"/>
???????<filter start="false">
????????????<include expression="(.*)\.php"/>
????????????<include expression="(.*)\.sh"/>
???????</filter>
???????</plugin>
</head>
?
?
vim /etc/rsyncd.secret
abc123@#$
Chmod 600 /etc/rsyncd.sercret
啟動sersync
/usr/local/sersync/sersync2 -d -r -o?/usr/local/sersync/confxml.xml
echo /usr/local/sersync/sersync2 -d -r -o?/usr/local/sersync/confxml.xml?>> /etc/rc.local
以后重啟系統(tǒng)以后才能正常同步
腳本監(jiān)控sersync
sersync腳本會自動關(guān)掉,因此需要寫一個腳本自動的去檢測該進(jìn)程是否存在,不存在就啟動,腳本內(nèi)容如下:
vim??check_sersync.sh
#!/bin/bash
# usage:
#1.Copy Shell To SersyncPath
# ??????chmod +x checkrsync.sh
# ??????2.Add Crontab
# ??????*/5 * * * * [sersyncPath]/checkrsync.sh
?
logfile='/var/log/sersync/checksersync.log';
?
function sersync_is_running(){
threadnum=`ps aux|grep sersync2|grep -v grep -wc`;
if [ "$threadnum" -eq '0' ];then
echo '0';
else
echo '1';
fi
return;
}
?
function current_time(){
if [ -z "$1" ];then
????????????????format="%Y-%m-%d %H:%M:%S%Z";
????????else
????????????????format=$1;
????????fi
????????echo `date +"$format"`;
????????return;
}
?
function logtofile(){
echo $(current_time) $2>>$1;
}
?
function sersync_restart(){
/usr/local/sersync/sersync2 -r -d -o /usr/local/sersync/confxml.xml >/dev/null 2>&1;
sleep 3;
?
threadnum=$(sersync_is_running);
if [ $threadnum -eq '0' ]; then
echo "0";
else
echo '1';
fi
return;
}
?
isrunning=$(sersync_is_running);
?
if [ "$isrunning" -eq '0' ];then
logtofile $logfile "sersync service was died.";
?
restart=$(sersync_restart);
?
if [ $restart -eq '0' ];then
logtofile $logfile "sersync service restart failed.";
else
logtofile $logfile "sersync service restart success.";
fi
else
logtofile $logfile "sersync service is running.";
fi
?
exit 0;
?
?
crontab -e
*/5 * * * * /root/tools/check_sersync.sh >/dev/null 2>&1
sersync腳本有時候會卡死,因此需要隔一段時間重啟一下,腳本內(nèi)容如下:
Vim sersync.sh
?
#!/bin/bash
set -x
SERSYNC="/usr/local/sersync/sersync2"
CONF_FILE="/usr/local/sersync/confxml.xml"
PIDSTAT=`ps -ef |grep 'confxml.xml' |grep -v grep |awk '{print $2}'`
kill -9 $PIDSTAT
#pkill ?sersync2
#pkill ?sersync2
rm -rf /tmp/rsync_fail_log.sh
STATUS=$(ps aux |grep 'confxml.xml'|grep -v 'grep'|wc -l)
if [ $STATUS -eq 0 ];
?
then
???????
???????$SERSYNC -d ?-r -o $CONF_FILE &
?
else
?
???????exit 0;
?
Fi
?
crontab -e
?
0?*/10?* * * /root/tools/sersync.sh >/dev/null 2>&1
?
總結(jié):通過以上幾步以后,你從服務(wù)器的/data/test就能夠從主服務(wù)器實(shí)時更新,升級的時候只升級主服務(wù)器的文件,從服務(wù)器也會自動同步過去,減少你的工作量以及出錯的概率!如果讀者想了解更多的信息,請直接訪問sersync開發(fā)者的博客,博客里有更詳細(xì)的說明!
http://blog.johntechinfo.com/sersyncguild
插件相關(guān)
如上面的xml所示,其中plugin標(biāo)簽設(shè)置為true時候,在同步文件或路徑到遠(yuǎn)程之后后,調(diào)用插件。通過name參數(shù)指定需要執(zhí)行的插件。目前支持的有command refreshCDN socket http四種插件。http插件目前由于兼容性原因去除,以后會重新加入。
以下模塊(command refreshCDN http socket)可以單獨(dú)使用(發(fā)生文件改變不同步只調(diào)用插件),只需在命令行下使用-m 參數(shù)即可。如果需要作為插件與同步程序一起使用,見同步程序說明的插件配置。
command插件
<plugin name="command">
????????<param prefix="/bin/sh" suffix="" ignoreError="true"/>
???????<filter start="false">
????????????<include expression="(.*)\.php"/>
????????????<include expression="(.*)\.sh"/>
???????</filter>
?</plugin>
當(dāng)文件同步完成后,會調(diào)用command插件,如同步文件是test.php,則test.php文件在改動之后,調(diào)用rsync同步到遠(yuǎn)程服務(wù)器后,調(diào)用command插件,執(zhí)行
/bin/sh test.php ?suffix?>/dev/null 2>&1
如果suffix 設(shè)置了,則會放在inotify事件test.php之后
如果ignoreError為true,則會添加>/dev/null 2>&1
當(dāng)然還可以設(shè)置command的filter,當(dāng)filter為ture,include可以只對正則匹配到的文件,調(diào)用command。
refreshCDN 插件
“refreshCDN”,就在同步過程中將文件發(fā)送到目 的服務(wù)器后刷新cdn接口。如果不想使用,則將start屬性設(shè)為false即可。如果需要使用其他插件,則查看其他plugin標(biāo)簽,將插件名稱改為 xml中其它插件的名稱即可。該模塊根據(jù)chinaCDN的協(xié)議,進(jìn)行設(shè)計,當(dāng)有文件產(chǎn)生的時候,就向cdn接口發(fā)送需要刷新的路徑位置。刷新CDN模塊 需要配置的xml文件如下。
?
<plugin name="refreshCDN">
<localpath watch="/data0/htdocs/cms.xoyo.com/site/">
<cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
<sendurl base="http://pic.xoyo.com/cms"/>
<regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
</localpath>
</plugin>
其中 localpath watch 是需要監(jiān)控的目錄。
cdnifo標(biāo)簽制定了cdn接口的域名,端口號,以及用戶名與密碼。
sendurl標(biāo)簽是需要刷新的url的前綴。
regexurl標(biāo)簽中的,regex屬性為true時候,使用match屬性的正則語句匹配inotify返回的路徑信息,并將正則匹配到的部分作為url一部分,
舉例:
如果產(chǎn)生文件事件為:/data0/htdoc/cms.xoyo.com/site/jx3.xoyo.com/image/a/123.txt
經(jīng)過上面的match正則匹配后,最后刷新的路徑是:
http://pic.xoyo.com/cms/jx3/a/123.txt;
如果regex屬性為false,最后刷新的路徑是
http://pic.xoyo.com/cms/jx3.xoyo.com/images/a/123.txt;
socket插件
socket插件,開啟該模塊,則向指定ip與端口發(fā)送inotify所產(chǎn)生的文件路徑信息。
Http插件
http插件,可以向指定域名的主機(jī)post,inotify監(jiān)控的事件。
單獨(dú)運(yùn)行插件
插件也可以單獨(dú)使用,即不對遠(yuǎn)程目標(biāo)機(jī)進(jìn)行同步,直接調(diào)用插件:
只調(diào)用command插件
./sersync -d -m command
只調(diào)用refreshCDN插件
./sersync -d -m refreshCDN
只調(diào)用socket插件
./sersync -d -m socket
只調(diào)用http插件
./sersync -d -m http
?
轉(zhuǎn)載于:https://www.cnblogs.com/centos-python/articles/8531992.html
總結(jié)
以上是生活随笔為你收集整理的Sersync实现触发式文件同步的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见网络游戏同步方式
- 下一篇: tp5,thinkphp5,隐藏inde