我是如何发布版本的
碎碎念
很久之前,当我最初接触后端代码的时候,并没有太过关心文件版本什么的问题,那时候简单粗暴的直接在服务器上修改。
后来慢慢的程序写的多了,功能复杂了,突然发现传统的简单粗暴带来的结果是,长时间的暂停服务。在你发布或者修改文件的时候,冷不丁的会出现个什么特殊情况,然后系统就会很无辜的无法正常运行,这时候你会发现,这个BUG或者问题可能你之前根本没有遇到过。接下来就是紧张的排查和修复了,快的话几分钟慢的话可能以天为单位,极端情况最后不得不还原之前的版本。
经过一段时间的折磨之后,终于开始想方设法的去优化这个发布流程了,于是:
前期准备
在解决新的发布流程之前,我做了下面一些或多或少和发布有关的工作:
- 开启CDN服务
- 前端资源的版本控制(这里用到的是我自己开发的mStaticizem,staticize.zhuwenlong.com,它可以把说有的静态资源文件加上版本号,并且替换所有引用的文件,这样可以最大程度的发挥CDN的价值)
发布流程&测试流程
通常情况下,会有开发服、测试服,甚至有些公司还会有预发服等一系列的测试环境。目的只有一个,为了更加可靠的发布代码。但是!这些服务器的存在某种程度上大大影响了发布时间。而且很多情况下是靠手动去传输文件,听说过这样的一个新闻:
国外某知名互联网公司CTO因为没有有效的手段控制发布故障、减少发布日的加班而引咎辞职。其继任提出了网站火车发布模型,自动化发布流程:人的干预越少,自动化程度越高,引入故障的可能性就越小,大家按时下班的可能性就越大。
可见发布流程其实应该是一件比较严肃且重要的事情,如果处理的好的话可以带来不少的好处。
实际流程
在和很多一线的小伙伴交流之后,我采用了这样的一套发布流程:
1.首先是开发
这个和大多数人采用的作法是一样的,有一套专门用于开发的服务器,所有新的featrue
分支的开发,以及自测都是在这台服务器上进行,接下来就是发布。
2.前端资源的处理
由于前端资源的特殊性,发布之前要对前端资源进行处理,包括以下的几个自动化步骤:
- CSS、JS文件的自动化合并压缩
- Image图片的自动化无损压缩,上面两部都是通过使用比较广泛的自动化工具 Grunt 来实现的
- 前端资源的版本处理,经常可以看到BAT公司的页面引入的CSS、JS地址是
xxx.b3adg.css
xxx.dgt6d.js
他们的所有静态资源都增加了版本号,包括所有引用的地方,如果是手动来做这样的实情,几乎就是不可能完成的任务,这里我用了自己的开发的一个前端集成工具 mStaticize 来实现的,它不仅可以替换文件名,甚至可以替换所有(比如说CSS,JS)中引用到这个文件的地址。
3.打包预发布
当前面的两部完成之后,我会把所有涉及到的文件,做成一个带有时间戳压缩包(比如zhuwenlong.com_20140301),并自动的上传到正式服务器上。
4.测试
当正式服务器接收到文件之后,会自动将相应的压缩包解压到指定的位置,并以端口递增的方式运行该服务,比如说之前运行的版本是 127.0.0.1:8999
,那么接下来新包的服务就是 127.0.0.1:9000
,请注意这些端口并不对外开放,只有内网可以访问到。你可呢会留意到,这时候其实线上会有很多个版本的服务同时运行,这点会在下一步阐述。到此,我们的新的包已经传到服务器上,并且以一个新的端口运行了,接下来就是测试了,这里其实不需要很多的人力的,简单的自动化跑一下新功能的单元测试脚本,然后如果不放心再人工去点点看,基本上问题不大。
5.一秒钟正式发布以及回滚
上一步有说到同时运行的多个服务,这里就派上用场了。当测试完成之后,只需要简单的修改nginx
的域名对应的端口映射,比如目前是127.0.0.1:8999
只需要修改成127.0.0.1:9000
那么就可以相当一个新的版本发布了,真的只需要1秒钟(可能有人会问这样切换的话,前端文件的浏览器缓存怎么办,这时候我们前面的第2部就派上用场了, mStaticize 已经很早就将修改过的静态资源替换成新的版本号了,你可以随意的在各个版本之间切换)。
接下来线上的老的服务怎么办?这里可以更具喜好选择保留时间,比如说1个月或者你喜欢永久保留。保留的目的是,当你发现新的版本有严重bug的时候,你可以1秒钟回滚到回老的服务。
这样一个完整的发布流程就轻松的结束了。