自动增量升级方案的设计及实现

发表于:2013-08-29来源:IT博客大学习作者:zhengzn点击数: 标签:增量
问题背景: 1. 能否以某种简便甚至自动化的方式,将修改过的文件以增量的方式同步到线上而不影响应用的正常运行。 2. 除了文件同步外,能否自定义某些脚本,在升级时自动执行。

  问题背景:

  1. 能否以某种简便甚至自动化的方式,将修改过的文件以增量的方式同步到线上而不影响应用的正常运行。

  2. 除了文件同步外,能否自定义某些脚本,在升级时自动执行。

  3. 如果发现升级后的版本有问题,能否快速回滚到原来的版本。

  写作目的:

  1. 以SVN为例子,学会基于版本库的自动增量升级。

  2. 无需依赖任何文件同步工具,只需简单的几个shell脚本便可完成从自动增量打包到自动增量升级的整个过程。

  适合阅读对象:

  1. 想从繁琐乏味的升级工作中解放出来的运维人员。

  2. 担心因修改文件数目多而可能导致升级遗漏的开发人员(尤其是web项目开发者)。

  3. 想了解自动增量升级设计思想的人员。

  不涉及的内容:

  1. 暂未包含基于hg或git版本库的增量升级的实现,但思路与SVN是类似的。

  2. 本文侧重业务应用的增量升级,不涉及个人软件或者系统软件的增量升级,尽管这两者存在一些相似的地方。

  脚本下载地址:

  https://github.com/joerong666/auto_patch.git

  正文:

  增量升级这个名词相信已经不是什么新鲜事物了,甚至我们每天在不经意间也已经做了该事。比如windows的自动更新,就是增量更新的一种。先撇开系统软件的升级不说,作为一个业务应用开发者,笔者这里就自己所了解,介绍一下业务应用在做增量升级方面都采用哪些方法。

  升级方法比较:

  方法一:逐个文件拷贝覆盖

  这个是最原始的增量升级方式,虽然简单,但繁琐且易漏易错,相信稍有点规模的应用都不会采用这种方式。想想如果有分布在不同子目录中的上百个文件被修改过了,你得执行拷贝覆盖多少次,更悲催的是,你花了九牛二虎之力才把文件拷贝好,结果却发现覆盖错了。

  方法二:使用类似rsync的文件同步服务器

  相对来说,使用rsync可以确保文件不会被误覆盖,也能保持目录结构的一致性。但个人觉得这只是一种文件同步,跟升级还是有一定的区别,如果我们的升级仅仅是涉及文件的覆盖或删除,或许采用rsync是一个不错的选择。但如果想在升级的同时自动执行某些定制的程序或脚本,那么rsync就显得有点爱莫能助了。另外rsync的引入,也需要额外的成本去搭建和监控它,自然也就需要额外的维护成本。而且rsync与版本库的无缝结合也是个值得考验的问题,能否由rsync直接从版本库中获取增量的部分,还是得额外写个脚本将增量部分写到rsync的同步目录中,再由rsync客户端来获取?

  方法三:由开发人员手工编写升级脚本

  一般来说,采用这种方法,首先需要开发人员记录下哪些文件涉及改动,当然可通过查看版本历史的方式来判断哪些文件需要做更新;然后再针对这些文件,逐条编写相应的用于覆盖或删除线上应用的copy或rm语句;最后将包含这些语句的脚本随增量文件一起打包给运维人员,让运维人员到线上执行。从可靠性的方面考虑,这种方式还不如第二种方法,但相对来说,这种方式的可控性比较灵活,可以灵活自定义升级脚本,而不是简单的同步文件。比如可以定义在升级的同时执行某个特定的程序,最常见的就是在升级的同时重启原来的某些服务。

  方法四:自动增量升级

  该方法是对方法三的一种增强,一方面是升级脚本是根据版本历史自动生成的,不再需要人工编写;另一方面,支持自定义升级扩展,也就说除了生成简单的增量覆盖升级脚本外,还支持以可插拔式的方式将自定制的程序让升级脚本自动执行。这是笔者选择的升级方法,也是本文的讲述重点。下面针对这种方法具体展开描述。

  自动增量升级:

  下面先从流程方面来大概介绍一下自动增量升级的整个思路,然后再从程序的角度解释一下本文中所涉及的脚本的作用。

  升级流程:

  升级流程分两个阶段,第一阶段为增量打包操作,一般由开发人员执行;第二阶段为升级操作,可由运维人员执行。

  增量打包流程:

  流程描述:更新版本库 ===> 生成增量清单文件 ===> 检查并修剪清单文件(以及编写自定义升级程序) ===> 生成增量补丁包

  对应命令或脚本:svn update ===> gen_manifest.sh(需将结果重定向到PATCH_MANIFEST清单文件) ===> 添加或删除清单文件(PATCH_MANIFEST)中无需做更新的记录(同时根据需要编写想让升级程序自动执行的脚本,如 demo_custom_script.sh) ===> gen_patch.sh

  升级流程:

  流程描述:获取增量包 ===> 执行升级操作并生成增量包的回滚备份包

  对应命令或脚本:可通过wget获取增量包 ===> patch.sh(执行完后会生成增量回滚包,如patch_recover_20130626113450)

  程序解释:

  生成清单文件gen_manifest.sh:

  $ ./gen_manifest.sh

  Usage: ./gen_manifest.sh revision1[:revision2] [sub_dir]

  该脚本用于生成增量清单文件,既然是增量,就需要有一个相对版本,所以至少需要传入revision1这个版本参数,其值为上次程序发布时的版本库版本号加 1。默认情况,该脚本会生成当前目录及其所有子目录下(递归)的增量清单,如果只需要针对某个子目录,则可指定sub_dir。因一般情况下该脚本生成出来的清单都需做一定的修剪,为了可直接供管道使用,这里并没有让它输出到文件,而是直接输出到标准输出,使用者可根据需要直接重定向到 PATCH_MANIFEST(这个文件名是gen_patch.sh脚本约定好使用的,不能为其它名字)文件。

  清单文件PATCH_MANIFEST,大体如下:

  #revision:A/D/C:src_file[:dest_dir]

  r2061:A:sub_dir/dir1/a.java

  r2065:A:sub_dir/dir2/b.sh

  r2069:A:script/dir3/c.ini:sub_dir/script/dir3

  #r2111:D:sub_dir/test/kkk/tt.txt

  #r2112:A:sub_dir/test/kkk2

  #r2112:D:sub_dir/test/kkk

原文转自:http://blogread.cn/it/article/6550?f=wb