欺壹世充電系列之[Svn集中式版本管理系統]

Svn集中式版本管理系統

                                     --欺壹世充電系列

一、svn服務器


1、什麼是Svn

svn(subversion)是一個垮平臺的開源版本控制系統。管理隨時間改變的各種數據。svn會備份並記錄每個文件每一次的修改更新變動,這樣我們就可以把任意一個時間點的檔案恢復到想要的某一箇舊的版本。


2、Svn與Git

svn是集中式的管理,存在一箇中央版本庫,所有開發人員在本地開發所有使用的代碼都來自於這個版本庫,提交代碼也都必須提交到這個中央版本庫。

svn版本控制系統流程如下:

1.在中央庫上創建或從主幹複製一個分支。

2.從中央庫checkout下這個分支代碼。

3.添加自己的代碼文件,修改現存的代碼或者刪除代碼文件。

4.commit代碼,假設有人在剛剛的分支上提交了代碼,你就會被提示代碼過期,你得先up你得代碼後在提交。up代碼的時候如果出現衝突,需要解決好衝突後再進行提交。


缺點:

如果無法連接到中央版本庫的環境下,你無法提交代碼,將代碼加入版本控制,無法查看代碼的歷史版本,以及版本變化過程。由於代碼庫集中管理,因此,需要對中央版本庫的存儲做備份。svn的備份要備份所有代碼數據以及所有更改的版本記錄。


git

分佈式的版本控制,由linus開發,所有很自然的git和linux文件系統結合比較緊密,以至於在windows上你必須使用cygwin才能使其完美的工作。

那git憑啥叫做分佈式的版本控制系統呢?還是從其工作模式講起吧。

git中沒有了中央版本庫的說法了,但是爲了開發小組的代碼共享,我們通常還是搭建一個遠程的git倉庫。但是和svn不同的事,開發者本地也包含了一個完整的git倉庫,從某種程度上說本地的倉庫和遠程的倉庫在身份上是等價的,沒有主從之分。

如果你的項目是閉源項目,或者你習慣於以往的集中式的管理模式的話,那麼在git下你也可以像svn那樣的工作,只是流程中可能會增加一些步驟。

1)你在本地創建一個git庫,並將其add到遠程git庫中。

2)你在本地添加或者刪除文件,然後commit,當然conmmit操作都是提交到本地的git庫中了。(其實是提交到git目錄下的objects目錄中去了)

3)將本地git庫的分支push到遠程git庫的分支,如果這個時候遠程git庫中已經有別的人push過,那麼遠程git庫將不允許你的push,這時候你需要先pull,然後如果有衝突,處理好衝突,commit到本地git庫後,在push到遠程git庫。


優點:

你可以不鏈接遠端git服務器而在本地也可以做版本控制(類似於單機版本庫)。


3、svn的服務端運行方式

1)獨立服務器訪問

訪問地址如:svn://svn.xxx.com/sadoc;

2)藉助apache等http服務

訪問地址如:http://svn.xxx.com/sadoc;

a、單獨安裝apache+svn

b、csvn(apache+svn)是一個單獨的整合的軟件,帶web界面管理的svn軟件。

3)本地直接訪問(在svn服務器本地訪問的方式)

訪問地址:file://application/svndata/sadoc;


4、svn的安裝

對於svn的安裝的話一般沒有特殊需求的話,可以直接yum安裝。

[root@localhost ~]# uname -rm
2.6.32-573.el6.x86_64 x86_64
[root@localhost ~]# rpm -qa subversion
subversion-1.6.11-15.el6_7.x86_64
如果沒有的話:yum install -y subversion


5、配置svn

爲了可以統一管理svn,我們單獨創建data和passwd文件夾

[root@localhost ~]# mkdir -p /home/svndata
[root@localhost ~]# mkdir -p /home/svnpasswd

啓動svn服務

[root@localhost conf]# svnserve -d -r /home/svndata/
[root@localhost conf]# ps -ef|grep svn
root     22266     1  0 17:27 ?        00:00:00 svnserve -d -r /home/svndata/
root     22268 22241  0 17:27 pts/6    00:00:00 grep svn
[root@localhost conf]# netstat -lntup|grep svn
tcp        0      0 0.0.0.0:3690                0.0.0.0:*                   LISTEN      22266/svnserve

建立項目版本庫,項目可以創建多個,這裏只創建一個演示,

svnadmin create /home/svndata/sadoc(不可用mkdir,因爲需要svn初始化很多東西)
可以加 --fs-type ARG指定文件格式。

修改配置文件

[root@localhost conf]# diff svnserve.conf svnserve.conf.bak 
12,13c12,13
< anon-access = none#-->禁用匿名訪問
< auth-access = write #--?開啓寫權限
---
> # anon-access = read
> # auth-access = write
20c20
< password-db = /home/svnpasswd/passwd   # 更改目錄到集中管理目錄
---
> # password-db = passwd
27c27
< authz-db = /home/svnpasswd/authz     # 更改目錄到集中管理目錄
---
> # authz-db = authz

創建用戶

[root@localhost ~]# cp passwd authz /home/svnpasswd/
[root@localhost ~]# cd /home/svnpasswd/
[root@localhost ~]# chmod 700 *
[root@localhost svnpasswd]# vi passwd 
### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.
[users]
# harry = harryssecret
# sally = sallyssecret
qishi = qishi123    #-->添加用戶
linzhiling = linzhiling    #-->再添加一個
**更改svnserve.conf時候需要重啓svn,更改authz和passwd的時候不需要重啓svn。

賦權

[root@localhost svnpasswd]# vi authz 
### This file is an example authorization file for svnserve.
### ======中間註釋略==========
### grant read ('r') access, read-write ('rw') access, or no access
sagroup = qishi,linzhiling
[sadoc:/]
qishi = rw #添加的用戶必須在passwd中存在的。
linzhiling = r
@sagroup = r    #添加的組要先創建。


權限格式:

用戶組格式:

[groups],其中一個用戶組可以包含一個或多個用戶,用戶間用逗號分隔。

版本庫目錄格式:

[<版本庫>:/項目/目錄]

@<用戶組> = <權限>

<用戶名> = <權限>

其中,方框號內部可以有多種寫法:

[/],表示根目錄及以下,根目錄是svnserve啓動時指定的,我們指定爲/home/svndata,[/]就是表示對全部版本庫設置的權限。

[repos:/]表示對版本庫repos設置權限;

[repos:/sadoc]表示對版本庫repos中的sadoc項目設置權限;

[repos:/sadoc/qishi] 表示對版本庫repos中的sadoc項目的qishi目錄設置權限;

權限主題可以使用戶組,用戶或者*,用戶組在前面加@,*表示全部用戶。

權限可以是w、r、wr和空、空表示沒有任何權限.


6、配置完畢重啓

[root@localhost ~]# pkill svnserve
[root@localhost ~]# svnserve -d -r /home/svndata/


二、svn客戶端軟件


windows下的svn

1、windows下svn的下載地址:https://sourceforge.net/projects/tortoisesvn/files/1.9.3/Application/TortoiseSVN-1.9.3.27038-x64-svn-1.9.3.msi/download?accel_key=61%3A1459244639%3Ahttps%253A//tortoisesvn.net/downloads.html%3A4b3a10d0%2434eeb3e5542aaed1d228cff451468585f45b0026&click_id=c32ead50-f592-11e5-bb77-0200ac1d1d9c-1&source=accel

2、安裝svn

windows下一隻下一步。

3、配置鏈接svn

1)創建一個目錄

2)鼠標右鍵選擇目錄,點擊選擇"svn檢出(k)..."

3)在彈出的對話框上填入以下相關信息,完成svn的鏈接並已完成了將文件庫下載到本地。

svn://xxx.xxx.xxx.xxx/sadoc

user:qishi

password:qishi123

4)使用:%APPDATA%\Subversion\auth  可以查看三個子目錄內保存認證信息。

5)svn顏色對應的操作:

藍色:提交一個修改

紫色:提交一個新增項

深紅:提交一個刪除或者替換

黑色:所有其他項

6)其他windows下的操作此處先略過,so easy。


Linux下客戶端管理

用法:svn<subcommand>[opthins][args]
 <子命令>[選項][參數]

部分常用命令

checkout(co) //從源碼庫取出一個工作版本的拷貝.
list(ls) [--verbose]//查看文件[顯示更詳細的信息]
cat svn://xxx.txt   //查看文件內容
commit(ci) //提交當前工作拷貝的更改。這個地方是有可能出現代碼衝突的。
update(up)//更新。
svn --help 查看所有命令

Linux下代碼的檢出、更新、提交

svn co svn://xxx.xxx.xxx.xxx/sadoc /mnt/svndata --username=qishi --password=qishi123    ##發現已經將代碼下載下來
svn update svn://xxx.xxx.xxx.xxx/sadoc /mnt/svndata --username=qishi --password=qishi123    ##發現已經將剛剛上傳的代碼更新過來了。
提示:如果遇到Can't convert string from 'utf-8' to native encoding 問題是因爲代碼中包含了中文,需要做字符集的調整:
export LC_CTYPE='en_US.UTF-8'
export LC_ALL=
問題解決。
svn add 111.txt
svn commit -m "this is test" 111.txt
 ###提交文件。

常見報錯

提示:如果遇到Can't convert string from 'utf-8' to native encoding 問題是因爲代碼中包含了中文,需要做字符集的調整:

export LC_CTYPE='en_US.UTF-8'
export LC_ALL=        #-->問題解決。

svn服務器上的本地訪問

svn co file:///home/svndata/sadoc


三、svn進階


1、svn目錄結構的規劃

svn:

branch 分支,爲測試時使用,幾天以上的項目必須開分支,測試需要本分之通過,主線合併到分支通過,才能合併到主線進行測試。

tag   版本記錄使用

trunk 主線,與正式線相對應,當天不上線文件不允許提交。


1)創建 主幹、分支、tag目錄並導入svn服務器

mkdir -p /svn/trunk /svn/branch /svn/tag
svn import /svn file:///home/svndata -m "import "


2)Linux下將主幹拷貝到分支。

svn copy svn://127.0.0.1/sadoc/trunk svn://127.0.0.1/sadoc/branch/branch_cms110329 -m "create a branch by qishi modifiy" --username='qishi' --password=qishi123


2、svn鉤子


svn鉤子就是被某些版本庫事件觸發的程序,例如:創建新版本或者修改未被版本控制的屬性。


每個項目下的hooks都有鉤子目錄,去掉.tmpl擴展名就可以使用了。


提示:由於安全原因,Subversion版本庫在一個空環境中執行鉤子腳本--就是沒有任何環境變量,甚至沒有$PATH或者%PATH%。由於這個原因,許多管理員會感到困惑,他們的鉤子腳本手工運行時正常,可在Subsersion中卻不能運行。要注意,必須在你的鉤子中設置好環境變量活爲你的程序制定好絕對路徑。


常用鉤子腳本:


1、post-commit 在提交完成成功創建版本之後執行該鉤子,提交已經完成,不可更改,因此,本腳本的返回值被忽略,提交完成時觸發事物。

2、pre-commit 提交完成前觸發執行該腳本。

3、start-commit 在客戶端還沒有向服務器提交數據之前,即還有建立Subsersion transaciton執行執行腳本。


非常用:

pre-revprop-change在修改revison屬性之前

post-revprop-change  在修改revison屬性之後

pre-unlock對文件進行解鎖操作之前

post-unlock 對文件進行解鎖操作之後

pre-lock 對文件進行加鎖操作之前

post-lock 對文件進行加鎖操作之後



生產環境應用:


1、利用pre-commit 限制文件擴展名及大小,控制提交要輸入的信息等。


2、post-commit 

svn更新自動周知,MSN,郵件或者短信周知,觸發checkout程序,然後實時rsync推送到服務器等。


案例一:rsync與svn鉤子結合實現數據實時同步某企業小案例

1、創建站點目錄  mkdir /home/wwwdata
2、同步代碼  svn co svn://127.0.0.1/sadoc /home/wwwdata --username=qishi --password=qishi123

**寫鉤子腳本重點:1、環境變量 2、全路徑


3、編寫鉤子代碼

#vim post-commit
#!/bin/sh
REPOS="$1"
REV="$2"
export LC_CTYPE="en_US.UTF-8"
export LC_ALL=
LOGPATH="/mnt/log"
[ ! -d ${LOGPATH} ] && mkdir ${LOGPATH} -p
#update content from svn
SVN=/usr/bin/svn
$SVN update --username=qishi --password=qishi123 /home/wwwdata
if [  $? -eq 0  ]
then
/usr/bin/rsync -az --delete /home/wwwdata/ /tmp/svnrsync
fi


注意:

1、給執行權限,chmod 700 post-commit

2、注意定義環境變量

3、儘量使用全路徑

4、在svn update之前一定要手動先checkout一下,因爲首次執行需要進行 yes等確認操作。


案例二:通過svn鉤子限制svn上傳大小、擴展名、及message長度

#!/bin/sh
REPOS="$1"
TXN="$2"
#此處更改大小限制,這裏是5m
MAX_SIZE=5242880
#此處增加限制文件後綴名
FILTER='\.(zip|rar|o|obj|tar|gz)$'
# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS"|wc -c`
if [ "$LOGMSG"  -lt 9 ]
then
echo -e "nLog message cann't be empty! you must input more than 8 chars as comment!" 1>$2
exit 1
fi
files=$($SVNLOOK changed -t $TXN $REPOS |cut -d " " -f 4-)
rc=0
echo "$files" |while read f;
do
#check file type
if echo $f|tr A-Z a-z|grep -Eq $FILTER;
then
echo "File $f is not allow($FILTER) file" 1>$2
exit 1;
fi
#check file size
filesize=`$SVNLOOK cat -t "$TXN" "$REPOS" "$f" |wc -c`
if [ "$filesize" -gt "$MAX_SIZE" ];
then
echo "File $f is too large(must <=$MAX_SIZE) B" 1>&2
exit 1
fi
done
# ALL checks passed, so allow the commit.
if [ $? -eq 1 ];
then
exit 1
else
exit 0 
fi

四、代碼上線方案及注意事項


##上線思想:

1、內網測試環境-beta環境-正式環境

2、原則影響用戶體驗最小

3、將代碼先上傳到臨時目錄,然後mv方式過去,因爲mv過程很短(php代碼不需要重啓http服務)。

4、儘量由運維人員管理上線,對於代碼的功能性,開發人員更在意,而對於代碼的性能優化和上線後服務器的穩定,運維更在意,因此,如果網站宕機問題歸運維管,就要讓運維控制上線更科學。否則開發隨意更新,出了問題運維負責,這就錯了。

5、上線前先備份,出問題及時回滾。

6、可採取先上線一般的應用服務器,測試無問題後 上另一半。


##代碼上線方案注意事項:

1、上線流程裏,辦公測試環境-->IDC測試環境-->正式生產環境,所有環境中的所有軟件均應版本統一,其次,應儘量單一,否側將後患無窮,開發測試成功,IDC測試也可能有問題。

2、開發團隊小組辦公內部測試環境測試(該測試環境屬於開發小組維護,或定時自動更新代碼),代碼有問題返回給某個開發人員重新開發。

3、有專門的測試工程師,程序有問題直接返回給開發人員,(此時返回的一般爲程序的bug,稱爲BUG庫),無爲題進行IDC測試。

4、IDC測試由測試人員和運維人員參與,叫IDCtest,進行程序的壓力測試,有問題直接返回給開發人員,無問題進行線上環境上線。

5、數臺服務器代碼分佈上線方案舉例(JAVA程序)

1)假設同業務服務器有六臺,將服務器分爲A,B兩組,A組三臺,B組三臺,先對A進行從負載均衡器上平滑下線,B組正常提供服務,避免服務器因上線影響業務。

2)下線過程是通過腳本將A組服務器從RS池(LVS,NGINX,HAPROXY,F5等均有平滑方案)中踢出,避免負載均衡器將請求分發給A組服務器(此時的時間應該爲網站流量少時,一般爲晚上)

3)將代碼分發到A組服務器的站點目錄下,對A組服務器上線並重啓服務,並由專門的測試人員進行訪問測試,測試成功後,掛上A組服務器,同時下線B組服務器,B組代碼上線操作測試等和A組相同,期間也要觀察上線提供的服務器狀況,有問題及時回滾。

6、特別說明:如果是php程序,則上線可以簡單化,直接將代碼(最好全量)發佈到所有上線服務器的特定目錄後,分發完成後,一次性mv或ln到站點目錄,當然測試少不了的,測試除了人員測試外,還有各種測試監本測試各個相關業務接口。

7、大多數門戶的前段頁面都已經靜態化或者cache了,因此,動態的部分訪問平時就不會特別多,流量低估時就更好了,再加上是平滑上下線,因此基本上對用戶體驗無影響的,當然也有上線出問題的情況,這個是避免不了的。

8、svn上包含代碼和配置。


五、參考上線架構圖

wKioL1b6ZaaBI7i4AAErVVSMMKQ015.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章