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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欺壹世充电系列之[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安装。

[[email protected] ~]# uname -rm
2.6.32-573.el6.x86_64 x86_64
[[email protected] ~]# rpm -qa subversion
subversion-1.6.11-15.el6_7.x86_64
如果没有的话:yum install -y subversion


5、配置svn

为了可以统一管理svn,我们单独创建data和passwd文件夹

[[email protected] ~]# mkdir -p /home/svndata
[[email protected] ~]# mkdir -p /home/svnpasswd

启动svn服务

[[email protected] conf]# svnserve -d -r /home/svndata/
[[email protected] 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
[[email protected] 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指定文件格式。

修改配置文件

[[email protected] 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

创建用户

[[email protected] ~]# cp passwd authz /home/svnpasswd/
[[email protected] ~]# cd /home/svnpasswd/
[[email protected] ~]# chmod 700 *
[[email protected] 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。

赋权

[[email protected] 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、配置完毕重启

[[email protected] ~]# pkill svnserve
[[email protected] ~]# 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上包含代码和配置。


五、参考上线架构图

技术分享

本文出自 “欺壹世De博客” 博客,请务必保留此出处http://qiyishi.blog.51cto.com/5731577/1758131

以上是关于欺壹世充电系列之[Svn集中式版本管理系统]的主要内容,如果未能解决你的问题,请参考以下文章

工作中可能用到的——集中式版本控制系统SVN

工作中可能用到的——集中式版本控制系统SVN

SVN教程 -- 基于自己学习记录

git 笔记

有关版本控制--SVN

SVN就是这么简单