Web应用部署最佳实践

少于 1 分钟读完

原文

本文帮助我们在开发流程中理解如何更好地完成部署工作,同时提供了一些跟部署有关的最佳实践供参考。

有时一个较差的生产环节部署行为能够毁掉研发工作的所有努力和投入,拥有可靠的部署流程能够为团队带来巨大的好处。

在进入正文之前,建议读一下Developing and Deploying with Branches,了解一下在代码库中如何使用分支的基本概念。

注意development分支

本文中会多次引用名为development的分支,在不同的版本控制系统里都有能完成这个开发目的的分支,比如Git中是master、SVN中是trunk,因此没有必要专门创建名为“development”的分支,本文之所以要用这个名字是为了在所有的版本控制系统中统一概念。

Web开发免责声明

我们对Web应用开发非常熟悉,但没有其他软件部署的经验,本文很适合跟我们类似的Web开发团队。

流程

部署工作应该被当作开发流程的一部分,而不应该独立在开发工作之后。建议从事Web应用开发的工作流程里,至少包含三个环境:Deveolopment、Staging、Production。

Staging,不知道该用什么样的专业名词,UAT环境?“准生产”环境?验证环境?

在这个基础之上,总体开发流程大致如下:

  1. 开发人员使用单独的分支处理bug和开发特性,确实是非常小的更新可以直接提交到比较稳定的development分支上
  2. 特性分支开发完成后,需要合并到staging分支,然后部署到staging环境,用于测试和质量保证
  3. 测试结束后,特性分支被合并到development分支中
  4. 发布时,development分支并合并到production分支中,然后部署到production环境

下面我们具体分析一下如何能更高效地完成各环节的部署工作。

开发环境

进行Web应用开发时,不需要专门的远程开发环境,每个开发者都应该在本地创建一套。

我们发现有些团队在每次提交或push时自动向共享的开发环境部署代码,这样做确实有一些优势,比如不需要每个人都建立一套开发环境,不过却有点得不偿失,这样做反而浪费了大量的时间。在这种情况下,即使是微小的变更都必须要在提交、推送、部署之后才能得到验证,如果变更本身存在问题,开发人员将不得不做回滚、重新推送、重现部署。

在本地环境进行测试就消除了提交、推动、部署的需要,每个变更都能够首先在本地获得验证,当这些变更基本稳定后,就可以被推到staging环境完成质量保证的测试。

我们不建议使用development分支向development环境快速地推动代码,在本地环境直接进行测试是最好的选项。

验证(staging)环境

特性分支开发完毕而且也基本稳定了,就可以被合并到staging分支并自动部署到staging环境,质量保证工作就可以启动了,测试人员此时可以进入staging服务器验证代码是否能够如预期的那样工作。

在代码库里使用独立的名为staging的分支对应staging环境是很容易的,这就允许开发人员同时向同一个环境部署多个特性分支,只要将需要质检的特性分支合并到staging分支就可以了,这样也有助于测试人员了解当前存在于staging服务器上的代码状态,他们只要去看staging分支的网络图就够了。

我们建议对staging分支的提交或推送操作执行自动部署到staging环境的操作。

生产环境

特性分支通过测试环节后,就可以被部署到生产环境了。此时特性分支应当被合并到development分支,然后特性分支就可以直接删除掉了,以避免困扰其他团队成员。

下一步是看看production分支和development分支的差异,快速地看看将被部署到生产环境的代码,这是最后的纠错机会了,看看还有哪些内容或代码不应该被部署到生产环境去。比如调试器断点、罗嗦的日志或不完整的特性、不正确的配置内容等。

一旦完成差异评审,就可以将development分支合并到proudction分支,然后把production分支部署到生产环境中,注意,这时请手动操作。请为这个部署操作指定一个有意义的信息,这样能让团队确切地知道生产环境的状态。

我们建议总是把主要版本按计划部署到生产环境,而且整个团队要非常明确这个时间计划。一般都是在应用程序使用量最不活跃的时段进行更新和升级,这听起来很简单,但实际操作要考虑整体安排。需要避免非常晚的时段,因为有人要在部署后监控几个小时,确保部署工作正常。还要保证紧急的生产环境修正能随时部署。

部署工作完成后,需要验证生产环境是否能正常工作,最好检查所有被部署的特性和修复能够正常工作。同时,每个部署工作结束后都向团队成员发送一封概述邮件,有助于他们确切了解已经上线的内容,最好是部署环节自动发送。

至此,部署完成。

回滚

常言道天不如人愿,十常八九。有时部署工作并不能按计划完成,或者部署干脆就失败了,这时就必须要考虑回滚了。不过回滚行为要异常慎重,有时回滚带来的伤害远大于修复出现的问题。因此首先要保持冷静,不要轻举妄动,在执行回滚之前,请先回答如下问题:

是我部署的代码出现了问题,还是其它地方出现了问题?

You can only rollback files that you deployed, so if the source of the issues is something else a rollback won’t be much help.

是否有可能回滚这个release?

不是所有的release都能够被回滚,有时一个发布改变了数据库的结构,而这个新结构有不能跟上一版本兼容,这时回滚的话,整个应用程序都将崩溃。

如果对这两个问题的答案都是“是的”的话,就可以安全回滚。回归后继续按照上面讲到的分支配合完成修复工作。。

部署紧急修复

有时我们需要向生产环境快速部署bug修复,而development分支还不具备发布release的条件。此时可以将bug修复分支直接同时合并到development分支和production分支,但不再需要把development分支合并到production分支,然后如常部署production分支。这样既能解决紧急的要求,又能避免development分支没有就绪的干扰。

这个情况向将bug分支同时合并到development分支和production分支是非常重要的,能保证未来发布时从development分支向production分支合并包含这个bug修复的结果。否则未来向生产环境部署,合并了没有纳入此bug修复分支的development分支,就会重新出现这个bug。

生产环境自动部署

我们认为向生产环境部署时应该由专人手动完成,这非常重要。在生产环境里使用自动部署非常危险,容易导致不可预期的结果。如果对production分支的提交或推送都会触发自动部署的话,某人由于失误在半夜里向production分支提交了不完整的代码,大家就不能安心睡觉了。在生产环境使用自动部署,会使其相当脆弱,请一定不要这么做。生产环境的部署一律靠手工操作

权限

每个开发人员都能够向staging环境部署,他们只需要确保部署时不覆盖其他人的变更即可。staging分支之所以很有好处,就是因为它把所有工程师的变更合并到了一起。

生产环境,应当只能被少数几个富有经验的开发人访问。这些家伙随时准备在部署出现问题时立即修复问题。

结论

我们使用这个流程好多年了,刚开始的时候学习成本有点高。现在我们的开发流程变得越来越高效和安全(我们同时部署几十台服务器),真心希望这篇文章能够对你们的开发工作有所帮助。