导读:作者吕毅在blog.lvscar.info发表了本篇文章,文中分享了Joel Test 、预发布环境、Tag发布机制以及可重复的部署过程等。内容如下:
周末聚会,无意间聊起建筑行业。自己是搞软件开发的,我们的行业从建筑设计/施工过程中借鉴了大量的概念,隐喻,名词。可以说软件就是现实中伴随整个人类历史发展的“建筑”在虚拟空间中的投影。有个两年前问过其他朋友的问题,这次友人又再次提起,“为什么建筑设计过程中没有普遍性的采用版本控制呢?”瞎扯了一干各种原因后,我们几乎同时想到一个名字”Joel”,建筑设计行业或许缺乏像Joel Spolsky一样十数年如一日,把自己丰富的经验和深入的思考转化成一篇篇文章以向新人传授软件开发过程中那些容易被忽略的概念。高傲的黑客们会对CMMI之类的认证抱以鄙夷之情,但对Joel整理出的12条写出更好软件的”最佳实践”,大家甚至把此称为审视其他团队开发过程的“Joel TEST”以推崇
这12条测试如下:
1.是否启用版本控制?
2.是否可以一步构建?
3.是否进行每日构建?
4.是否有bug跟踪列表?
5.是否在修改bug后,才开始写新代码?
6.是否及时更新工作计划?
7.是否在开发前编写了大家一致认可的功能文档?
8.是否有安静的工作环境?
9.是否在使用最好的软件开发工具?
10.是否有专职测试人员?
11.是否在面试时以实际编写代码来检查求职者?
12.是否利用陌生人进行可用性测试?
你所在的团队符合其中的几条呢?觉得这些条目太一般,软件开发原本就该如此? Joel Test写于十年前,一个Windows XP,Mac OS X,Ubuntu都还没有面世的年代。如果你觉得这些条目有些过时了,Google中搜索“Joel Test”,你可以看到这十年内很多对此进行更新的尝试,比如这两个页面“The Joel Test Update for 2010″,“Joel Test for web dev”.
我的主要工作集中在”Web/Mobile Web”领域,在”Joel Test”写就的年代,Web技术仅仅是一些用记事本就能写出的Html页面。但到了今天,到了经历过BS浪潮,后端编程语言井喷涌现,Ajax和HTML5变得人人皆知的今天。Web技术已经变成了一个由N种后端技术*N种开发语言/框架*N种前端技术交织起来的复杂体系。Web程序员们觉得Joel开出的列表仍然有价值,那是因为我们的大部分工作仍然延续着上一代程序员们开创的轨迹;我们仍然在通过程序代码释创造力同时避免BUG的出现;我们仍然得谨慎的在强大,华丽与高效之间做着权衡.相比客户端,Web技术最大的优势在于部署成本的节省,我们的程序和Joel年代最大的区别也在于此。这一年来新的工作岗位让我学到了很多,部署过程正是其中我觉得最值得和大家分享的部分.
下面这个列表来自前阵子看到的一篇很好的文章Staging Servers, Source Control & Deploy Workflows, And Other Stuff Nobody Teaches You,标题中的列出的三项和我的体会高度吻合,下面我会对他们一一做出自己的诠释
1.是否采用了预发布环境
2.是否以Tag作为发布单位
3.是否让部署过程是可重复的
是否采用了预发布环境
关于测试驱动开发的鼓吹中,”免除对代码修改的恐惧”十分具有诱惑力.我们都不喜欢功能逐渐丰富过程中冷不防出现的各种BUG,这些BUG打乱我们的计划,破坏我们的心情,从而让我们对开发新功能的旅程心存恐惧.TDD的最大魅力也来自于通过测试先行来保证后续的功能扩展相对于预期是可验证的.不过无论你的WEB开发过程是怎样的,最终的代码和内容还是要通过发布来送达到用户浏览器中,你可以对PK需求,修改BUG,延长加班毫无畏惧,但你不能忽略用户体验.代码一旦部署到正式环境上,对你工作的评判不再是项目组中关心你,体谅你的同事.而是千万对错误零容忍的用户.在发布前你已经做过周全的测试?新增的每一项功能已经测试过?很好.不过是在你的开发环境或某处偏僻的”测试环境”中?服务器OS不一样,Web Server有差别,缓存服务未启用,APP容器或解释器,数据库版本有差别,没接通第三方API,这所有的一切都可能会造成发布后,你自己或用户刷新网站后的那声”What The fuck?”,我想这应该是较之修改BUG,你更不想面对的情景吧.
总的说来,”预发布环境”就等于没有真实用户访问的生产环境,除了让用户不能访问到外,尽一切可能让这个环境和生产环境一致.每次正式发布时以这个环境为目标,测试流程完成后.把发布内容从这个环境”平移”到生产环境.
是否以Tag作为发布单位
从业几年来,”所在团队把SVN当FTP用”是几乎每次朋友们互相吐槽时都能听到的话题,”SVN的分支合并太难用;需要更密切和团队伙伴共享工作内容…”我们可以很轻松的找到不创建功能分支然后进行合并的理由,事实上这么做可能也有一定的”合理性”.但发布时打个Tag,对你的现有开发流程几乎不会带来负担.你不需要切换到Git或Mercury,唯一要做的只是在提交后,发布前运行一行svn copy命令,然后在发布目标上用svn switch命令代替svn update来更新代码.只有一点需要注意,创建Tag的svn copy命令的目标最好是一个新的SVN仓库地址(新Tag路径),而不是本地目录.这么做的理由是当以仓库路径作为svn copy目标时,不会产生文件拷贝,而以本地路径为目标执行时,会发生文件拷贝,如果项目包含很多文件,这个过程会较为漫长.如果想避免本地打tag时的文件拷贝,你可切换到分布式版本控制系统.
这么做的好处也是明显的,虽然我们已经通过预发布环境规避了大部分发布环境可能引入的问题.但当那”万一”发生时.你能够以最快的速度切换到上一次发布时的状态.通常可以通过”$svn switch[上次发布Tag的SVN路径]“一行命令搞定.
是否让部署过程是可重复的
如果你所在的团队对开发和运维工作进行了严格切分,这不会是一个问题.但不是所有项目都会到这个规模,如果你是一个幸福的能变更生产环境的Web程序员,请千万小心,你对生产环境的每次调整/优化,都可能让项目部署过程变得不可重复.随着时间的推移,你会忘记当时的配置项.一旦项目需要扩容,恢复,移交.这过程都可能演变成灾难.
上面提到那篇文章中,提倡用部署脚本来管理部署过程.这是很好的解决方法,但如果你暂时缺乏系统脚本编程能力.分门别类把每次环境配置过程记录清楚吧,就当这项工作要在你不在场的情况下被别人重复执行.
别人说我们是”码农”,我们要把自己当工程师.