我們平時上傳程式碼,可以通過ftp
、sftp
等將檔案上傳至伺服器,耗時耗力,而且很容易出錯。如果伺服器數量少還好,一但伺服器數量增加,壓力可想而知。
這個時候我們可以使用各種工具進行檔案同步,方法很多,這裡推薦大家使用rsync+sersync
進行檔案同步。
這裡使用伺服器A和伺服器B進行介紹,我們的目的是將A伺服器指定的目錄自動同步到B伺服器指定的目錄。
使用rsync+sersync的背景故事
擼了快 3 年的 Laravel 了,儘量這周分享本人使用的多臺伺服器叢集部署方案
rsync
是linux
下同步檔案的一個高效演算法,用於同步更新兩處計算機的檔案和目錄,並適當利用查詢檔案中的不同塊以減少資料傳輸。rsync
的主要特點就是增量傳輸,只對變更的部分進行傳輸。
sersync
利用inotify
與rsync
對伺服器進行實時同步,其中inotify用於監控檔案系統事件,其優點是隻對檔案不同的部分進行操作,所以其優勢大大超過使用掛接檔案系統的方式進行映象同步。
關閉伺服器selinux
$ vi /etc/selinux/config #編輯防火牆配置檔案
#SELINUX=enforcing #註釋掉
#SELINUXTYPE=targeted #註釋掉
SELINUX=disabled #增加
:wq! #儲存,退出
然後重啟伺服器生效
B伺服器安裝rsync
$ yum -y install rsync
$ systemctl start rsyncd.service #啟動rsync服務
$ systemctl enable rsyncd.service #將rsync服務 加入開機自啟
檢查是否已經成功啟動,使用ps命令
$ ps -ef | grep rsync
編輯B伺服器rsync配置檔案
$ vim /etc/rsyncd.conf
log file = /var/log/rsyncd.log #日誌檔案位置,啟動rsync後自動產生這個檔案,無需提前建立
#pid file = /var/run/rsyncd.pid #pid檔案的存放位置
lock file = /var/run/rsync.lock #支援max connections引數的鎖檔案
secrets file = /etc/rsync.pass #使用者認證配置檔案,裡面儲存使用者名稱稱和密碼,後面會建立這個檔案
uid = root #設定rsync執行許可權為root
gid = root #設定rsync執行許可權為root
use chroot = no #預設為true,修改為no,增加對目錄檔案軟連線的備份
max connections = 1200 #最大連線數
timeout = 600 #設定超時時間
[book] #自定義名稱
path = /data/book/ #rsync服務端資料目錄路徑
comment = book #模組名稱與[book]自定義名稱相同
port=873 #預設埠
read only = no #設定rsync服務端檔案為讀寫許可權
list = no #不顯示rsync服務端資源列表
auth users = bookuser #執行資料同步的使用者名稱,可以設定多個,用英文狀態下逗號隔開
hosts allow = A伺服器IP #允許進行資料同步的客戶端IP地址,可以設定多個,用英文狀態下逗號隔開
hosts deny = 192.168.0.1 #禁止資料同步的客戶端IP地址,可以設定多個,用英文狀態下逗號隔開
建立使用者認證檔案
$ vi /etc/rsync.pass
設定使用者名稱和密碼,使用者名稱和密碼之間以英文冒號分隔
bookuser:123456
設定檔案許可權
$ chmod 600 /etc/rsyncd.conf #設定檔案所有者讀取、寫入許可權
$ chmod 600 /etc/rsync.pass #設定檔案所有者讀取、寫入許可權
重啟rsync
$ systemctl restart rsyncd
防火牆開啟873埠
centos7
預設是firewall
,如果防火牆是iptable
,對應更換即可
$ firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="A伺服器IP" port protocol="tcp" port="873" accept" #開放埠
$ systemctl restart firewalld #重啟防火牆
$ firewall-cmd --list-all #檢視規則是否生效
A伺服器安裝rsync
參照B伺服器安裝rsync
A伺服器建立密碼認證檔案
$ vi /etc/passwd.txt #編輯檔案,新增以下內容
123456 #密碼 ,B伺服器裡設定的密碼
:wq! #儲存退出
$ chmod 600 /etc/passwd.txt #設定檔案許可權,只設定檔案所有者具有讀取、寫入許可權即可
到此,rsync已經配置完畢
測試A、B伺服器之間同步
$ rsync -avH --port=873 --progress --delete /www/data/ bookuser@B伺服器IP::book --password-file=/etc/passwd.txt #在A伺服器下執行
如果出現連線失敗,基本是埠問題,檢查阿里雲安全組埠是否開啟\
成功的話,見下圖
evernotecid://97CFF20F-9983-4C0A-BC5A-6B2E3E6658E1/appyinxiangcom/15428497/ENResource/p438
安裝sersync
連結:https://pan.baidu.com/s/1GcIlOIsyM8-E1INpQ...
提取碼:p0df
解壓檔案
$ tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz #解壓
$ mv GNU-Linux-x86 /usr/local/sersync #移動目錄到/usr/local/sersync
修改inotify預設引數(inotify預設核心引數值太小)
$ vi /etc/sysctl.conf #新增以下程式碼
fs.inotify.max_queued_events=99999999
fs.inotify.max_user_watches=99999999
fs.inotify.max_user_instances=65535
:wq! #儲存退出
配置sersync
$ cd /usr/local/sersync #進入sersync安裝目錄
$ cp confxml.xml confxml.xml-back #備份原檔案
$ vi confxml.xml #編輯,修改下面的程式碼
<?xml version="1.0" encoding="ISO-8859-1"?>
<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>
<exclude expression="^static/*"></exclude>
</filter>
<inotify>
<delete start="true"/>
<createFolder start="true"/>
<createFile start="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="false"/>
<modify start="false"/>
</inotify>
<sersync>
<localpath watch="/data/book">
<remote ip="192.168.1.200" name="book"/>
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
<commonParams params="-artuz"/>
<auth start="true" users="bookuser" passwordfile="/etc/passwd.txt"/>
<userDefinedPort start="false" port="873"/><!-- port=873 -->
<timeout start="false" time="100"/><!-- timeout=100 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/rsync_fail_log.sh"timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="true" 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"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
<filter start="false">
<include expression="(.*)\.php"/>
<include expression="(.*)\.sh"/>
</filter>
</plugin>
<plugin name="socket">
<localpath watch="/data/book">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<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>
</head>
引數說明:
<localpath watch="/data/book"> #源伺服器同步目錄
<remote ip="192.168.1.200" name="book"/>
remote ip="23.225.218.182": #目標伺服器ip,每行一個
name="book": #目標伺服器rsync同步目錄模組名稱
<auth start="true" users="bookuser" passwordfile="/etc/passwd.txt"/>
start="true" #設定為true,每隔600分鐘執行一次全盤同步
users="bookuser": #目標伺服器rsync同步使用者名稱
passwordfile="/etc/passwd.txt": #目標伺服器rsync同步使用者的密碼在源伺服器的存放路徑
failLog path="/tmp/rsync_fail_log.sh" #指令碼執行失敗日誌記錄
手動測試執行同步命令
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml
執行後,命令列輸出:
檢視execute,複製程式碼 cd xxxx .txt 手動執行一遍,無誤後,基本可以確定成功
如果修改了配置檔案,需要殺掉之前的近程再執行上述程式碼
$ killall sersync2 #殺掉全部近程
設定sersync監控開機自動執行
$ vi /etc/rc.d/rc.local #編輯,在最後新增一行
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml #設定開機自動執行指令碼
:wq! #儲存退出
如果不起作用的話\
進入 /etc/init.d 目錄,建立指令碼sercync.sh\
編輯內容
#!/bin/bash
# chkconfig: 2345 10 90
# description: resind
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml
然後賦予執行許可權
$ chmod +x sersync.sh
將指令碼新增到系統服務
$ chkconfig --add sersync.sh
設定開機自啟動:
$ chkconfig sersync.sh
至此,檔案自動同步部署完成
附錄:rsync常見問題及解決辦法(IP以10.10.10.10代替)
錯誤一:
password file must not be other-accessible
continuing without password file
Password:
rsync客戶端路徑是否寫錯,許可權設定不對,需要再次輸入密碼,客戶端和服務端的密碼檔案都應該是600的許可權才可以
錯誤二:
@ERROR: Unknown module ‘bak’
rsync error: error starting client-server protocol (code 5) at main.c(1522) [receiver= 3.0.3]
服務端server的配置中的[bak]名字和客戶端client的10.10.10.10::bak不符
錯誤三:
rsync: failed to connect to 10.10.10.10: Connection timed out (110)
rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.6]
檢查服務端server服務是否正常啟動,檢查埠防火牆,iptables開啟873埠
如果服務端是windows server則在防火牆入站規則中增加873埠
如果服務端是Linux則先檢查服務是否啟動#ps aux | grep rsync
然後開啟873埠#iptables -A INPUT -p tcp --dport 873 -j ACCEPT開啟873埠
附:
安裝rsync yum install rsync
啟動服務/usr/bin/rsync --daemon
啟動服務錯誤failed to create pid file /var/rsyncd.pid: File exists
看看提示服務錯誤的路徑(這個路徑不一定就是這個,看自己的報錯路徑)這裡是/var/rsyncd.pid所以
rm -rf /var/rsyncd.pid;再重新啟動Rsync服務
此時在看一下ps aux | grep rsync啟動成功
錯誤四:
@ERROR: access denied to gmz88down from unknown (10.10.10.10)
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]
看看是不是服務端server hosts allow限制了IP,把這裡的IP加入到服務端server的hosts allow白名單中,windows rsync不能寫多個allow,可以在一個allow中加多個IP,例:hosts allow=10.10.10.10 20.20.20.20
錯誤五:
@ERROR: chdir failed
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]
服務端server的目錄不存在或者沒有許可權(要同步的那個檔案路徑),安裝windows rsync時候會建立一個SvcCWRSYNC使用者,這個使用者對要拷貝的目錄沒有許可權,方法一,將這個使用者給許可權加入到目錄中,方法二,修改這個使用者隸屬於的組,修改後要在管理中重啟服務
錯誤六:
rsync error: error starting clie
nt-server protocol (code 5) at main.c(1524) [Receiver= 3.0.7 ]
/etc/rsyncd.conf配置檔案內容有錯誤,檢查下配置檔案
錯誤七:
rsync: ch
own "" failed: Invalid argument (22)
許可權無法複製,去掉同步許可權的引數即可
錯誤八:
@ERROR: auth failed on module bak
rsync error: error starting client-server protocol (code 5) at main.c(1530) [receiver=3.0.6]
密碼錯誤或伺服器上是否有bak模組
錯誤九:
rsync: connection unexpectedly closed (5 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]
模組read only = no設定為no false
錯誤十:
@ERROR: invalid uid nobody
rsync error: error starting client-server protocol (code 5) at main.c(1503) [sender=3.0.6]
設定
uid =0
gid = 0
錯誤十一:
rsync: failed to connect to 10.10.10.10: No route to host (113)
rsync error: error in socket IO (code 10) at clientserver.c(124) [receiver=3.0.6]
防火牆原因
錯誤十二:
rsync: read error: Connection reset by peer (104)
rsync error: error in rsync protocol data stream (code 12) at io.c(759) [receiver=3.0.6]
/etc/rsyncd.conf配置檔案不存在
錯誤十三:
rsync: Failed to exec ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(84) [receiver=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: error in IPC code (code 14) at io.c(600) [receiver=3.0.6]
需要在客戶端安裝yum install -y openssh-clients即可