zoukankan      html  css  js  c++  java
  • “持续集成”的可持续困局

    “持续集成”的可持续困局

    持续集成的最终目标是允许团队在任意时间部署除了最近几个小时之外的所有工作成果 —— 《Agile Development》

    代码随时可以交付是软件开发团队希望达到的一致目标,通过引入持续集成能够帮助团队接近这一目标,为何要说“接近”,而不是“达到”呢?因为大多数团队对于持续集成的理念很大程度停留在“工具”这个概念层级,也即认可持续集成是一种帮助团队提高效率的有效工具,而没有把它当成方法论。在这个层面上,团队实际关注点是“自动化”,包括构建、部署、测试自动化,通过自动化释放重复劳动对团队生产造成的人力、时间成本的浪费。因此团队引入持续集成的速度是惊人的,几乎是在一夜之间团队就可以拥有一套完整地持续集成环境,团队成员惊奇的发现原本让人痛苦的版本集成,现在已经变成了完全自动化的计算机任务,一切看上去是如此完美。

    完美吗?不,其实不完美。大多数拥有持续集成的团队,很快都会遇到一个棘手的问题——如何推进持续集成,让其发挥长期的效能。这就又回到了软件开发的老问题上来:有关软件开发的所有问题,都是人的问题。持续集成面对的和所有的敏捷软件开发实践一样,都是软件开发最佳实践与软件开发人员个人习惯的矛盾。为何这样说,让我们重新审视持续集成的经典步骤:

    1. 持续集成服务器不断才版本控制服务器上检查代码状态是否存在更新;
    2. 从版本控制服务器下载更新代码;
    3. 自动化编译
    4. 自动化测试
    5. 自动化代码分析
    6. 产生可执行软件

    从步骤描述上看,上述过程似乎不需要开发人员参与,实际上每一步却都与开发人员密不可分,特别是步骤3、4、5,在很大程度上依赖于开发人员持续不断的反馈,比如编译出现的错误、测试发现的问题、代码分析检出的缺陷,都需要开发人员持续关注。因此可以说持续集成的核心就是通过自动化套件与开发人员间持续反馈共同实现,整个过程从形式上构成环环相扣的PDCA,两者缺一不可,尤其当缺少开发人员的持续反馈时,持续集成所期望实现的闭环系统就被彻底破坏,而这恰恰是持续集成最容易出问题之处。毫不夸张的说,至少在笔者工作的公司大多数团队宣称的持续集成只能称之为自动化构建,开发人员对反馈的漠视或是拖延几乎是这些团队的通病。

    一个人做一件好事并不难,难的是一辈子做好事

    是否有办法来应对持续关注的缺失呢?答案是肯定的,并且对这个问题的解答有一个几乎所有介绍极限编程书籍都会提到的统一的标准答案--团队持续集成纪律。这个答案存在一个未决的问题:如何去让团队执行团队持续集成纪律。现实中的团队不会像书本中描述的那样永远充满能力,充满正面、积极向上的情绪,对于团队制定的纪律会坚定不移地去执行。在大多数情况下,现实团队的状态总是处在起伏过程中,开发人员不是工业时代异化的生产机器,刻板、墨守成规,而是游走在规则和创意之间的精灵,因此工作状态的起伏势必影响纪律的执行程度。更加常见的情况是团队组成不是自愿的,而往往是通过调令,也就意味着团队领袖只能看菜下饭,因为大部分“材料”都已经有了自己习惯的工作方式,能够做的只是微调。

    如果再考量一下纪律一词,百度对于“纪律”的解释是这样的:纪律是指为维护集体利益并保证工作进行而要求成员必须遵守的规章、条文。纪律具有强制性,一定集体的纪律一经制定,每个成员就必须执行,违法了纪律,就要受到批评惩罚。也就是说团队持续集成纪律隐含着对违反纪律成员的惩罚,是否惩罚、如何惩罚却从来没有提及过,而且惩罚适用于有严密组织体系的单位,特别是存在阶层的情况下,但在软件从业者来看这样的前提几乎不存在,甚至适得其反,因此团队对于纪律的破坏大多采用了包容的态度。

    基于上述分析可以得出一个结论:大多数团队对于持续集成的使用是有限的,这里指的有限包含两层含义:

    • 对持续集成投入精力有限
    • 对破环持续集成的惩罚有限

    由此看来持续集成面临的最大问题是可持续,并且从前面的论述看出深层次的可持续问题难以解决,那么是不是就认为这样的问题没办解决了?其实解决方法还是有的,还是那个标准答案——团队持续集成纪律,关键不在于纪律本身,而在于如何施加约束使得团队能够自觉或不自觉地运转纪律,从而形成弱于纪律的团队成果——团队持续集成习惯。

    要形成持续集成习惯,关键要解决两个问题:

    • 如何让开发人员关注持续集成
    • 如何让开发人员快速反馈

    对于第一个问题,大多数团队通常的做法是邮件列表,这真的不是一个好的选择,而且是一个容易造成开发人员漠视或拖延的选择,原因很简单,开发人员的精力是有限的,开发是主线任务,而查阅邮件非常容易把开发人员的时间碎片化。同时开发人员不仅要处理持续集成产生的邮件,同时还要处理其他邮件,邮件优先级的排序团队无法介入,也就难以保证持续集成邮件优先处理。此外邮件内容也容易对开发人员产生迷惑,由于协同开发的原因,多名开发人员会参与到同一个模块,而持续集成产生的邮件反馈只能做到将分发给所有参与的开发人员,无形中耗散了无关开发者的精力,以编译输出为内容的邮件也不便于直接定位。无法做到所见即所得会让开发人员迅速地产生疲劳,笔者在处理类似邮件时深有体会,很多时候选择直接删除。

    主一无适便是敬——梁启超《敬业与乐业》

    最佳的能让开发人员迅速关注的持续集成的方式是刺激开发者的神经,例如ThoughtWorks使用的火山灯。这样的方式很直观,直接刺激开发者的视听,但也会存在意想不到的问题,例如笔者所在的团队采用音频刺激的方式,当出现失败的构建或测试时,会发出刺耳的警报声,起初效果很不错,团队成员对新奇玩意保持很高的热情,但很快问题来了,笔者工作场所并不是只有笔者团队,还有大量的其他团队,这些团队提出了抗议,警报声影响了他们团队的正常工作,同时团队也逐渐地习惯了刺耳的警报,团队又回到了原来的状态。所以这种直接的刺激虽然效果很好,但需关注使用的场合和时效,任何能够短期奏效的方法都是存在保质期的。

    也许最有效的方式是和开发人员的IDE结合在一起,IDE插件会接受持续集成服务器的消息,不断地以弹窗的形式提醒开发人员关注问题,并快速修复

    最佳的持续集成习惯形成的时机是团队组建前,这样会避免后续引入时带来的过渡适应期,因此引入持续集成的时机很重要,越早引入越容易让团队习惯持续集成,并且可以制定大量相应的规则,这样便会让团队成员先去学习使用适应规则,省去了后期引入持续集成时,团队成员强烈的反弹(例如单元测试覆盖率指标,代码规范性指标等)。很可惜这样的场景很少会出现,大多数团队都是在版本出现严重问题时才想起需要引入持续集成,这时的引入不免会产生已有开发习惯和新晋规则的对立,如果团队下定决心推进,尚有成功的可能性,否则极大的几率会出现走样和变形,到最后团队只记住了使用的工具,忘记了持续集成的初衷。

    谈到第二个问题,其实更加复杂,要想快速反馈,必须要让开发人员学会小步提交、版本控制。也许有人会觉得这很简单,但日常的生活经验告诉我们一个道理,越是简单的事,要做到做好越不容易。大多数团队和开发人员都非常习惯和享受一次性提交大量代码,这是一种成就感的体现,却不是一个好的开发实践,这意味着回退的代价将是相当可观的,可观到以至于开发人员都不愿意去触碰,一旦小步提交没做好,糟糕的版本控制就会像流感一样到处传播,有时候几个开发人员同时出现问题就会导致几天无法产出版本。对待这个问题实在没有太好的解决方案,因为笔者也经常会犯这样的错误,这种源自内心的诱惑力实在是太大了。

    持续集成不单是自动化地持续叠加,更要求开发人员持续地给予反馈,持续集成的可持续依赖于团队、依赖于开发,从这个层面上讲,可持续不存在90%的成功,任何一次松懈都会是前功尽弃的结果。虽然上文给出了很多解决方案,但是这些方案也存在太多的限制,持续集成的可持续不会有一个标准的统一解决方案,只能找到最适合自身团队的。

    后记,笔者对于持续集成的可持续问题也正处在一个困惑时期,如果有人有任何可以推动持续集成的高招,都可以随时联系笔者,笔者将感激不尽

  • 相关阅读:
    2019.6.20刷题统计
    36 线程 队列 守护线程 互斥锁 死锁 可重入锁 信号量
    35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型
    34 进程 pid ppid 并发与并行,阻塞与非阻塞 join函数 process对象 孤儿进程与僵尸进程
    33 udp 域名 进程
    32 粘包 文件传输
    31 socket客户端. 服务器 异常 语法
    30 网络编程
    29 元类 异常
    26 封装 反射 常用内置函数
  • 原文地址:https://www.cnblogs.com/hxfirefox/p/4593830.html
Copyright © 2011-2022 走看看