文章
主题列表

最新资讯
持续交付(Continuous Delivery)故事分享
在长春评估期间,有一项目经理跟我说自己很头疼,说:“今天在客户那里做最后验收演示,程序就是跑不出来,本来测试时好好的。”


很多银行特别注重这类问题,但不同银行还是有差异:我有大陆C银行的U盾,使用特别方便,U盾插入电脑端接口,自动安装就好了;但是B银行却不然,当我换了一个MS Surface windows10,它的U盾就不能正常使用,技术人员远程协助都无法解决。可想象我只是B银行全国众多使用 Win10 Surface系统进行网上银行操作的用户之一,如若全国都按前面这样的处理方法手工部署处理,质量成本会多高,问题多严重。
如果常出现以上情况,你很可能须要关注持续交付(Continuous Delivery)。
因测试产品的环境,可能只是个开发环境,跟部署或验收环境不同,便可能导致很多未知问题的发生。
以下我们看几个常见例子:


1) 手工部署 (Manual Build)


要准备一个很详细的文档,描述每步部署如何做,哪一步容易出错,也依赖人工测试来确保程序可以跑通,实施人员遇到问题解决不了,只能去问开发人员,导致发布时间延迟,因为现在的应用软件都比较复杂,包含很多中间件,很多配置,任何一步都可能出错。如果人工部署,发布耗费的时间会较长,整个发布部署风险也会比较大,很可能会导致我刚才说的场景。反过来如整个部署都是自动的话,就能减少了这类问题。


2) 开发完成后,才开始部署生产环境(Production Environments)


测试人员一直到最后阶段还是在开发机器上测试软件,因为测试都是在内部机器做,做验收的客户代表,都没见过软件真正操作情况,他们第一次见到软件是在发布阶段,因一直都没人来搭建生产环境,或者觉得成本太昂贵,所以放到最后。
然后开发团队把所有的安装、文档配置、数据库迁移、部署文件等,交给安装工程师,但是一切都未在真正的投产环境测试过。开发团队和部署的工程师也没有沟通。
好的做法就是把测试、部署、发布涵盖在整个开发过程中,不要等到最后,避免这类问题。


3) 手工配置管理生产环境(Manual Configuration Management of Production Environments)


例如:入手更改生产应用服务器的配置参数,并手工把更新记录在变更管理系统中。
这可能导致一直在测试的环境都没问题,但到生产就失败;也会发现在不同的部署环境,表现出来的性能不同,因为人工配置管理操作,要准备整个部署也非常耗时。
因配置管理没做好,如果某个发布测试失败,无法倒退到前一个成功的状况;也难以看到不同操作系统的不同版本,包括一些程序包,一些补丁,一些软硬件的配置对不上。
当整个从测试到投产环境的配置是手工管理,会有很多未知之数,大家可想象如果使用自动配置管理系统来管,就可以避免刚才的问题。


配置管理


要解决上面这些问题,就要做好配置管理,很多人说:"我们已经使用了版本管理工具",有版本管理工具绝不等同于你已做好配置管,你可先问问自己以下问题:


  1. 能否很准确地重建整个环境 —— 包括操作系统、版本、补丁、网络、软件和应用软件等?

  2. 可不可以增量(incremental)改变环境的每个部分?

  3. 能不能很清晰看到每部分发生了什么变更,追溯到每一变更是哪人做,什么时候?

  4. 是否每个团队成员都可以容易查找到需要的信息?然后做所需的改变?也确保不影响最后交付,也不会导致延期?


最后一点很重要,很多公司的配置管理策略可以做到前面3点,但对每个人可以看到所有的信息却做了很多限制(希望信息保密) ,反而不利于配置管理。


我们现在CMMI评估都要求客户用维基平台来写故事,我们可以查看变更历史,也可以撤回错误的改变,有基本版本管理功能。

有人就说,你用这个平台好像违反了信息安全的原则。我说,“首先登录是需要密码,而且信息安全和信息的畅通是相对 - 如果你要最好的信息安全就什么都不放,那么很多信息就不透明,同样道理,维基平台能让所有人看到变更的历史,这也方便所有人知道相关的变化,不用每次都问配置管理员或项目经理。”
最近为一个上海客户做差距分析,我问他的需求分析人员,"需求文档一直有更新变化,你们如何可以知道你什么时候做了什么变化?“
他打开需求文档,我说请你打开你的变更历史页,发现是空的。我就跟他说,”如果你只是靠人手来记录什么时候做了什么变更,理论上可以,但是实际上很难执行,通常我们很多公司会用一些有版本管理功能的软件,你就可以跟踪所有的文档的变化,也可以撤回一些错误的改变。
10年前我看我师傅 Mr Kasse 关于CMMI 配置管理的解读,里面讲到配置项,包括工具,平台,测试步骤等等,当时我感觉为什么要包括那些?不是管好代码或相关文档就够了吗?现在从持续交付的角度看,这些元素也是配置管理的重要部分,否则会影响最后交付。

要做好配置管理,要注意以下3点:

  • 管理整个应用软件的构建,部署,发布等过程,前面应如何做好准备?可否把所有这些都做好版本管理,和之间的依赖(dependencies)管理

  • 管理应用软件本身的配置

  • 整个环境的配置管理:包括软件,硬件,软硬件平台,从操作系统到服务器,数据库,或者其他用到的商业软件等

如想深入了解,可参考 Humble:'Continuous Delivery'

持续集成(Continuous Integration CI)

持续集成是敏捷的重要部分,现在我们回顾一下,怎么可以做好持续集成,如何准备:

  • 要有版本管理

  • 要可以自动构建

  • 每当我听到团队还是手工构建,我很奇怪为何不把它自动化,如果我们要持续集成,每天都要构建,包括自动测试

  • 要有团队的赞同

  • 持续集成是个最佳实践,不仅仅是工具,需要整个团队高度付出参与与纪律,每个人频繁每个小步小步交付他的开发部分。也应该把任何影响软件的变更尽快解决,可以看参考文章 "Continuous integration on a dollar a day",作者提到如何不用任何自动化工具(但作者用了一橡皮鸡 Rubber Chicken),其实也可以做到持续集成

如何开始持续集成(CI)

有很多开源的软件可以下载来用,选好你要用的持续集成(CI)软件后,你就开始要安装使用,希望在利用工具来做自动构建,跟安装其他软件一样,开始的时候会遇到困难,你可以在你项目的wiki记录下来,让其他人知道,避免以后重复错误。接下来,大家可以开始用服务器持续集成:

  1. 当你准备好提交(check in)你的最近更改,要确保它是否能正常运行

  2. 它可以正常运行并通过测试,你应该把你的代码从你的开发环境提交到你的版本管理(Version control repository)系统去,也看有没有更新

  3. 跑构建脚本和测试,确保所有都可以在你的电脑正常操作

  4. 如果你在本地构建成功通过,就可以把你的代码提交到版本管理系统

  5. 让持续集成工具自动构建你提交的更新

  6. 如果不通过,你要尽快在自己的机器上修改问题,返回第三步

  7. 如果构建成功,你就可以进入下一步:完成

如果各成员都按照以上简单步骤,团队便有信心软件在任何电脑,同样配置,能成功运作,一些持续集成的注意点:

  1. 定时不断提交(Check in regularly),可以想象你写了很多代码才发现问题,后面你会花更大精力来找出问题

  2. 创建全自动化测试套件(Create an Automated Test Suite),很多资深的编码人员觉得自己写好代码就可以,不一定做单元测试,单元测试其实是复用率最高的,你可以想象你是持续集成的话,每次都可以靠测试来确保代码正确,如果没有单元测试就无法知道你的代码假如是有更改后,是否有错误 (注1)

  3. 保持较短的构建和测试过程(Keep the Build and Test process short),如果可以把测试和构建简短的话,就不会等到一大堆问题才要解决,就像我们把复杂的系统分成几个子系统,模块逐个开发的道理一样

  4. 管好自己的开发工作区(Manage your development workspace),不要只做好代码的版本管理,配置管理应包括你的测试数据,数据库脚本,构建脚本,安装脚本等,因为每一块都会导致你的软件运作不成功。

(注1: 如想多理解为什么单元测试很重要,可读我19年中的 “TDD 测试驱动开发与精益”文章)


从持续集成到持续交付


配置管理 与 持续集成(CI) 只是 部署(Deployment)流水线的基础。
部署(Deployment)流水线 可视作把软件产品从版本控制一直到交付客户的自动化过程, 包括:


提交(Commit)系统验收测试用户验收测试部署(Deploy)与发布(Release)


回到开始的长春例子,我就问那项目经理, 为什么他不考虑持续交付?
他问:持续交付如何可以帮助减少发生这类问题?
我跟他分享一个不是做开发也听得懂的故事:


我们现在写分享文章都已经使用维基服务器, 方便我们几位同事协同合作, 不须要像以前要把WORD文档传来传去。每人都可以编辑/更新服务器上的最后版本。服务器有基本版本管理功能。写文章可以选择增加一小段,并提交服务器保存;也可以选择一直本地编辑,到最终完成才提交。平常我都是选每一种方式,持续地不断提交。
有一次晚上,因为咖啡厅还有40分钟就打烊, 我便一直都没有提交。等到关门前提交时,服务器报错,说连接失败。因我没有预料会出问题,所以在提交前没有预先备份内容到本机。所以我辛辛苦苦30分钟的工作就没了。
你们现在的情况等同于那天咖啡厅的我。如果你们之前有利用自动化,测试,自动构件,脚本等。不断地在类似交付环境中持续测试/提交, 便可以避免你现在的困境。
我还好,只是一个人的30分钟时间。后面你们要解决问题很可能要多花几个星期甚至几个月的时间。


他问:为什么比你多这么长时间?
:软件系统与自然语言文章不一样。文字的容错度很高,我写错了一个字读写还可以99%看得懂。软件系统就不一样了,你写一个几十行的程序, 缺陷应该不超过半个小时可以搞定。但如果到了几万行,甚至几十万行的系统,你要找出缺陷并解决就非常困难了。所以我们要有测试驱动开发,持续集成的概念,达到每写一段代码都会有对应的测试,才可以确保软件正确。
最终交付可能出错的地方就更广泛: 可能是某些中间件的参数出错。可能是数据库的某个数据表不对。如果你们之前有从内部测试好的状态,管好到最终交付环境的配置管理, 不然就要像我咖啡厅的场景一样,最后要从头再做一遍。
最后,我看项目经理有了概念,我便介绍 部署(Deployment)流水线, 与持续交付 的原则:


  • 每一个与发布相关的东西都要版本管理,可以回滚 (Roll back)

  • 尽量全自动化

  • 利用自动化测试,持续集成,自动部署等尽早发现并解决缺陷

  • 把难题细化,(与敏捷的 Time Boxing 相似)频繁地做,减少最终的痛苦

  • 已发布才算完成 (DONE)

  • 反馈

    在发表前,我将文章发给一些客户朋友阅览,收获了一些很好的反馈:(也感激一南京顾问和杭州老朋友程总提的修正)
    某杭州总工的经验分享:

    早些年,大概是2014年以前,我们还没有持续集成的概念,项目结项验收的时候,发现很多项目不但所需要的东西不完备,而且东西拿来以后,不清楚怎么验证,好不容易将验证环境搭建好以后,发现根本无法按照预期那样进行运行。后来我们开始重视持续集成:

    1. 将传统的手工编译打包逐步过渡到通过Hudson、Jenkins进行自动编译打包;

    2. 在集成测试阶段,要求开发提供部署手册,根据手册部署独立的测试环境,存在问题要求开发提供支持并更新部署手册,保证按照手册可以顺利部署;

    3. 将开发环境、集成测试环境、用户模拟环境、用户实际使用环境完全独立开来,每个环境都需要验证通过才能进入下一步,这样保证开发出来的东西,部署得上去、用得起来、用得好。




    当然,持续集成需要软硬件环境的支持,也需要一定的人工投入。譬如,大数据类项目的集成,云环境类项目的集成,一个独立的环境需要几台甚至几十台的服务器资源支持,这是一个挑战。还有,对于GIS类项目,地图数据都是TB级别的数据量,准备数据或进行数据迁移,都需要很多人工投入。对于这些类型的项目,如果外部资源和人工无法得到保证的时候,往往就是开发好了,在开发环境进行集成以后,直接就上用户的生产环境了。
    一位很熟悉银行配置管理惯例的经理反馈:
    很多人分不清持续集成,持续交付的差别。也搞不懂配置实际上需要的是哪些环节。有必要做一些名词释义,以及过程拆解。
    一杭州金融产品公司总监反馈:
    广义的持续交付,是从业务/客户想法或需求,到业务/客户价值的交付。需要有强有力的软件架构、流程方法、IT平台工具、组织协同、组织文化支撑。
    一资深北京产品公司总监反馈:
    如果是开发系统提交到客户那边去测试集成 (不仅仅是企业内部开发系统交付上线 ), 就需要针对客户现场部署,尽早了解客户测试和生产环境,和他们的上线流程

    References

    Kasse, Tim: Practical insight into CMMI 2/e
    Humble, Jez: Continuous Delivery
    Shore, James: "Continuous integration on a dollar a day" (www.jamesshore.com)