參考資料:
http://svnbook.red-bean.com/en/1.5/svn.serverconfig.httpd.html#svn.serverconfig.httpd.extra.writethruproxy
背景/環境:
目前有一臺SVN服務器供全公司使用,但由於分公司數量的增加,且處於不同的地理區域的網絡中,造成了以下問題:
1.部分分公司的網絡狀況不佳,每次更新和提交代碼的時候都非常慢;
2.SVN服務器的壓力越來越大;
同時,很多分公司的領導都提出,希望能在本地建立一臺總部SVN服務器的鏡像,提升訪問速度;
方案/設計:
通過Apache的Write-through proxy使SVN服務器實現與MySQL Master-Slave類似的一主多從的架構。
如下圖所示:
安裝與配置:
1.安裝配置Apache與Subversion - Master&Slave
注:以下操作需要在Master與Slave上進行
首先,需要安裝和集成Apache與Subversion,具體的步驟可以參考我的這篇文章:
http://heylinux.com/archives/917.html
其中 第1段 和 第3段 分別講述了Apache與Subversion的安裝與配置方法。
2.檢查Apache是否加載proxy與proxy_http模塊 - Master&Slave
注:以下操作需要在Master與Slave上進行
# grep proxy /opt/apache2/conf/httpd.conf
如果出現以下內容,則表明加載成功:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
如果沒有出現,則需要通過以下方式添加:
進入Apache源碼包的modules目錄
# cd httpd-2.2.18/modules
# /opt/apache2/bin/apxs -c -i -a proxy/mod_proxy.c proxy/proxy_util.c
# /opt/apache2/bin/apxs -c -i -a proxy/mod_proxy_http.c
然後重啓Apache使模塊生效
# /opt/apache2/bin/apachectl restart
3.配置讀寫分離 - Slave
注:以下操作僅需要在Slave上進行
進入倉庫的主目錄
# cd /data/svn_repo
刪除在第1步中創建的倉庫
# rm -rf project1
創建新的空白倉庫
# /opt/subversion/bin/svnadmin create project1
更改倉庫目錄的屬主
# chown -R apache:apache project1/
創建pre-revprop-change鉤子文件
# cd project1/hooks/
# cp -p pre-revprop-change.tmpl pre-revprop-change
# chmod +x pre-revprop-change
# vim pre-revprop-change
刪除以下部分內容:
1 |
if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi |
3 |
echo "Changing revision properties other than svn:log is prohibited" >&2 |
更改Apache配置文件
# vim /opt/apache2/conf/extra/httpd-svn.conf
04 |
SVNParentPath /data/svn_repo |
07 |
AuthName "Subversion Repository" |
08 |
AuthUserFile /opt/subversion/conf/svn_passwdfile |
09 |
AuthzSVNAccessFile /opt/subversion/conf/svn_accessfile |
13 |
<Location /svn-proxy- sync > |
16 |
SVNParentPath /data/svn_repo |
19 |
Allow from 192.168.203.133 |
配置詳解:
首先,在>Location /svn>中加入 SVNMasterURI http://master.heylinux.com/svn 指定主SVN服務器的URL;
然後,創建一個新的>Location /svn-proxy-sync>,取消認證功能,並加入地址驗證,僅允許來自Master的請求;這樣,Master就可以通過 http://slave.heylinux.com/svn-proxy-sync/project1將代碼同步到Slave中去,避免了直接提交到http://slave.heylinux.com/svn/project1後會產生死循環的問題;
雖然,我們平時使用的是Slave - http://slave.heylinux.com/svn/project1,但在commit的時候,代碼會通過代理自動提交到Master - http://master.heylinux.com/svn/project1,然後再由Master同步到Slave中;
也就是說,我們在commit的時候,速度依然會受到與總公司Master服務器之間網絡的影響,但是本着80%與20%的讀寫比例原理,大多數時間下,我們都是以update爲主,而在執行Update動作的時候,我們的請求只會在Slave上,因此速度會很快。
4.配置鏡像同步 - Master
注:以下操作僅需要在Master上進行
進入倉庫的主目錄
# cd /data/svn_repo
創建pre-revprop-change鉤子文件
# cd project1/hooks/
# cp -p pre-revprop-change.tmpl pre-revprop-change
# chmod +x pre-revprop-change
# vim pre-revprop-change
刪除以下部分內容:
1 |
if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi |
3 |
echo "Changing revision properties other than svn:log is prohibited" >&2 |
初始化鏡像
# /opt/subversion/bin/svnsync init http://slave.heylinux.com/svn-proxy-sync/project1 file:///data/svn_repo/project1
執行後顯示以下信息則表明成功:
Copied properties for revision 0.
注意:如果是絕對路徑,file://後面還要加一個斜槓/,因此總共是三個斜槓,否則會出現以下錯誤:
svnsync: Unable to open an ra_local session to URL
svnsync: Local URL 'file://data/svn_repo/project1' contains unsupported hostname
進行初次同步
# /opt/subversion/bin/svnsync sync http://slave.heylinux.com/svn-proxy-sync/project1
執行後顯示以下信息則表明成功:
Transmitting file data .........
Committed revision 1.
創建 post-commit 鉤子文件
# cd /data/svn_repo/project1/hooks
# vim post-commit
更新 pre-revprop-change 鉤子文件
# vim pre-revprop-change
更改鉤子文件的屬主與權限
# chmod +x post-commit pre-revprop-change
# chown apache:apache post-commit pre-revprop-change
5.測試
配置完成,接下來便可以通過以下步驟檢查是否搭建成功。
a. 從Slave上checkout - 從Master上checkout - 向Slave上commit - 到Master上update
b. 向Master上commit - 從Slave上udpate
如果向Slave提交的代碼可以從Master上update下來,則表明Write-through proxy代理配置成功;
如果向Master提交的代碼可以從Slave上update下來,則表明鏡像同步配置成功;
6.其它
該文章中僅配置了一個Slave,如果在實際情況中需要配置多個Slave的話,只需要重複以上步驟並將Slave全部添加到Master的post-commit和pre-revprop-change鉤子文件中即可。