持续集成持续部署持续交付_持续集成反模式

在我的整个职业生涯中,我发现自己发现了对特定情况不起作用的东西,而不是对特定情况不起作用的东西, 可以学到更多。 例如,在我职业生涯的早期,为了快速发布软件,我跳过了单元测试,因为我认为付出的努力是不值得的。 幸运的是,我了解到将未经测试的代码投入生产是行不通的 ; 因此,我开始编写单元测试。

看来我们的行业在很大程度上同意我的学习风格; 实际上,我们甚至创造了自己的词汇来捕获在特定上下文中无效的实践: 反模式 。 从总体上讲,反模式似乎是有益的解决方案,但最终,它们会产生不利影响。

虚假证据真实存在

不幸的是,我还发现,当经验不足的团队尝试引入CI的做法时,他们很可能会错误地引入许多反模式,这最终可能导致人们对所谓的“恩惠”感到沮丧。 不幸的是,术语CI本身经常被盗用,因此,我经常听到诸如“ CI在大型项目中不起作用”或“我们的项目是如此独特以至于CI无法工作”之类的陈述,而实际上CI却没有。根本就是问题–某些做法的无效应用或不存在导致挫败感。

为了CI的缘故,我将继续保持记录,并在本文中详细介绍六个反模式:

  • 签入不频繁 ,导致集成延迟
  • 生成不完整 ,使团队无法继续执行其他任务
  • 反馈最少 ,可防止采取行动
  • 收到垃圾邮件反馈 ,导致人们忽略邮件
  • 拥有缓慢的机器 ,这会延迟反馈
  • 依靠a 肿的构建 ,这会减少快速反馈

如果您进行CI的时间足够长,几乎可以肯定的是,您将体验到这些反模式的效果。 没关系,但是如果它们发生得太频繁,将会限制CI的众多优势。 因此,如果您想限制这些反模式的发生和负面影响,那么本文适合您。

由于不经常签到而导致集成延迟

名称:不经常入住

反模式:由于任务需要进行大量更改,因此源文件会长时间从存储库中检出。

解决方案:频繁提交较小的代码块。

CI的前提是团队可以收到有关正在开发的代码状态的快速反馈; 而且,这种频繁的软件集成样式减少了更传统的后期样式“大爆炸”集成工作的时间(以及相应的痛苦)。 但是,有效的CI取决于定期发生更改的概念(因此,构建可能会频繁发生!)。 如果代码长时间驻留在台式机(而不是存储库)上,则会发生不好的事情,因为系统的不同部分正在发生其他更改。

本质上,通过不频繁提交更改,您将延迟集成,并且延迟时间越长,将需要更多的工作来解决不利影响(例如,其他人的更改影响您的代码)。 在使用CI的项目中,我建议开发人员每天至少提交一次代码,但是我认为最好每天多次检入代码。

任务更小,生活更轻松

我现在可以听到一些开发人员的愤怒,因为他们不可避免地抱怨说,当他们忙于修改这么多文件时,每天都很难检入代码。 从本质上讲,这句话是我的观点-要每天提交源更改,您需要考虑得更小。 实际上,您需要将编码任务分解为简洁的工作,以使更改量很小。

您不必像在编码原型上的read()write()update()delete()方法那样花大量精力在业务对象上实现所有功能,而是可以先对read()方法进行编码(以及相应的测试,对吗?),然后检入该类,以便随后集成整个代码库。 接下来,您可以实现另一种方法并遵循相同的实践,直到完成整个任务。 这样,您就可以最大程度地利用CI的优势,并极大地增强自己的信心,使您的代码一直与其他所有人的代码一起工作。

请记住,即使您和您的团队正确执行了许多CI实践,即使团队成员没有每天至少提交源更改,您的团队也会从CI中获得最小的收益。 而且通常会导致人们认为CI不起作用,这与事实相距甚远。

破碎的建筑减慢了发展的节奏

名称:破碎的建筑

反模式:构建会长时间中断,从而阻止开发人员签出正常运行的代码。

解决方案:在构建中断时,开发人员会立即收到通知,并将修复损坏的构建作为首要任务。

信不信由你,随着修复过程的延长,构建变得越来越麻烦。 这是因为有更多的文件,更多的更改和更多的依赖项,使得很难隔离缺陷。 因此,当某人(通过电子邮件,RSS或其他机制)被告知构建已被破坏时,修复有问题的方面应该是他们的头等大事; 否则,构建会中断的时间越长(尤其是对于频繁更改的团队),一旦有人决定采取行动,纠正这种情况就越难。

残破的构建并不总是一件坏事。 实际上,如果软件存在问题,则损坏的版本可使您快速学习。 当构建经常被破坏或被破坏太长时间时,被破坏的构建将成为一个问题。 如果构建损坏,您永远都不想离开办公室。

私人建筑可减少损坏的建筑

防止构建损坏的更有用的技术之一是在将代码提交到存储库之前运行私有构建 。 高层执行私有构建的步骤如下:

  1. 从存储库中检出代码。
  2. 在本地修改代码。
  3. 使用存储库执行更新以集成其他开发人员的更改。
  4. 运行本地版本。
  5. 构建成功后,将更改提交到存储库中。

图1演示了这种实践。 请注意,工作流程如何强调与存储库的频繁同步,从而允许定期检入并限制损坏的建筑-用一块石头砸了两只鸟!

图1.运行私有构建以减少损坏的集成构建
私人建造

通过在签入源代码之前执行私有构建(当然,这是经常发生的,对吗?),可以防止许多典型错误最终导致构建陷入崩溃状态。 因此,您可以节省时间和头痛。

以最少的反馈阻碍行动

名称:最小反馈

反模式:团队选择不向团队成员发送构建状态通知; 因此,人们并不知道构建失败。

解决方案:使用各种反馈机制来关联构建状态信息。

通常,在设置CI系统时,团队会认为接收电子邮件等同于垃圾邮件。 因此,他们决定“暂时”不会有任何通知。 但是,如果没有从构建中收到任何反馈,则无法采取任何措施。 实际上,反馈是CI最重要的方面之一。 话虽如此, 有效的反馈也至关重要。

如果要扩展将状态信息传递给团队成员的机制,则使用视觉和声音设备会非常有用,尤其是对于位于同一地点的团队。 诸如“环境球”之类的设备可有效提供建筑物状态的近实时可见性。 例如,当构建碰巧失败时,球可能会变成红色,而当构建通过时,球会变成绿色。 此外,球体可用于传播信息,例如通过更改不同的颜色(例如,蓝色代表好,黄色代表不好),代码库的循环复杂性在增加还是在减少。

让您的创意汁流淌

设置环境球并不容易。 清单1演示了如何使用Quality Lab的开源OrbTask在Ant中设置Ambient Orb:

清单1.使用环境Orb Ant任务
<target name="notifyOrb" >
  <taskdef classname="org.qualitylabs.ambientorb.ant.OrbTask"
    name="orb" classpathref="orb.class.path"/>
	<orb query="http://myambient.com:8080/java/my_devices/submitdata.jsp"
	  deviceId="AAA-9A9-AA9"
	  colorPass="green"
	  colorFail="red"
	  commentFail="Code+Duplication+Threshold+Exceeded" />    
  </target>

在清单1中,该任务被配置为将球体变为绿色(通过状态),将红色变为失败(状态)。 图2展示了一个绿色的球体,这大概意味着最近的构建状态是成功的:

图2.成功构建!
环境球

通过发挥创造力,您的团队可以利用各种反馈机制,使团队成员不会开始忽略构建状态消息。 而且,这些生动的技术使进入CI凹槽变得有趣。 此外,当有问题需要采取必要措施时,它们可以很容易地引起注意。

其他通知机制包括:

  • RSS订阅
  • 任务栏监视器,例如CCTray(用于CruiseControl)
  • X10设备(如LavaLamps)
  • 通过Jabber等发送即时消息
  • 短信(短信),针对那些未从亲朋好友那里收到足够信息的人

一个警告:您需要在太多信息和太少信息之间取得平衡。 您的反馈机制应有所不同,并根据工作环境定期更改。 例如,对于位于同一地点的团队,播放声音(如构建失败时发出的哨声)可能是有效的。 但是,其他团队可能更喜欢Ambient Orb(在您思想沉重时不一定会吓到您)。

垃圾邮件反馈的冷漠肩膀

名称:垃圾邮件反馈

反模式:团队成员很快会被构建状态电子邮件(成功和失败以及介于两者之间的所有内容)淹没,以至于他们开始忽略消息。

解决方案:反馈的针对性很强,因此人们不会收到不相关的信息。

与没有收到足够反馈的反模式相反,我经常会发现团队,他们天真地决定每当CI服务器执行任何操作时, 每个人都应该始终收到反馈(例如,电子邮件)。 没有什么比饱和状态大声尖叫“无视我”了。 反馈过多,您的团队将很快开始将CI反馈视为垃圾邮件。 然后,当出现严重问题(例如,构建实际上已损坏)时,可能会不被注意。

精确定位可以阻止垃圾邮件

在清单2中,示例CruiseControl配置文件演示了发送电子邮件通知的有效用法。 在这种情况下,无论构建成功与否,技术主管总是会收到电子邮件,仅在构建失败时项目经理才会收到电子邮件,并且最近对存储库进行源更改的任何开发人员也会收到电子邮件。已通知。

清单2.使用CruiseControl发送电子邮件通知
<project name="brewery">
...
<publishers>
  <htmlemail 
    css="./webapps/cruisecontrol/css/cruisecontrol.css"
    mailhost="localhost"
    xsldir="./webapps/cruisecontrol/xsl"
    returnaddress="cruisecontrol@localhost"
    buildresultsurl="http://localhost:8080"
    mailport="25"
    defaultsuffix="@localhost" spamwhilebroken="false"> 
    <always address="techlead@localhost"/>
    <failure address="pm@localhost" reportWhenFixed="true"/>
  </htmlemail>
</publishers>	
...

考虑到反馈是配置项系统最关键的方面之一,因此值得进行一些讨论。 尽管它们是频谱的相反方面,但是在最小反馈和垃圾邮件反馈之间仍然有一条细线。 当构建损坏时,必须及时将反馈发送给正确的人,并且必须向人们提供可行的信息。 如果构建成功,则应仅将其发送给进行了最近更改或处于领导地位的少数几个人,因此可能需要此信息。 始终用状态消息轰炸所有人是确保在短时间内限制CI流程收益的一种可靠方法。

不要因为机器慢而延迟反馈

名称:慢速机

反模式:使用资源有限的工作站作为构建机器,导致构建时间较长。

解决方案:构建计算机具有最佳的磁盘速度,处理器和RAM资源,可进行快速构建。

几年前,我在一个相对较大的项目中,该项目有超过一百万行代码,需要两个多小时来编译。 当我们尝试更频繁地集成时,等待配置管理团队完成此过程变得越来越痛苦。 当然,最好的情况是两个小时,因为构建通常会失败,因此该过程通​​常需要几天才能完成(谈论痛苦!)。 经过数周的缓慢运行之后,很明显的解决方案是购买一台具有足够磁盘空间的计算机,以用于所有由于构建而被检出并生成的文件,这是处理许多指令的最快处理器速度,足够的RAM用于运行测试和其他占用大量内存的进程。

您是否觉得需要速度?

使用这个怪物盒子,我们可以将建造庞然大物的时间从2小时减少到30分钟; 因此,将少量额外的钱投入到最先进的机器中所带来的好处最终为团队节省了可观的时间和金钱,并最终更快地集成了软件(这意味着我们可以更快地发现问题!)。

从额外的工作站开始执行集成构建没有任何问题。 但是,这个故事的寓意是,如果您发现构建机器的速度或内存落后,或者发现硬盘发生故障,则应该认真考虑升级构建机器。 通过加快构建速度而节省的时间可帮助您获得更快的反馈,Swift解决问题并更快地进行下一个开发任务。

膨胀的构建会延迟快速反馈

名称: lo肿的身材

反模式:将所有内容投入到提交构建过程中,例如运行每种类型的自动检查工具或运行负载测试,从而延迟反馈。

解决方案:构建管道允许运行不同类型的构建。

一些开发团队对可以添加到自动构建中的所有过程非常着迷,以至于他们忘记了执行这些操作需要花费时间 。 举例来说,还记得我的项目花了两个小时才能完成编译吗? 想象一下,如果我们在该构建过程中添加了执行测试。 拥有超过一百万行代码,您认为对代码运行静态分析工具将花费多长时间? 如果您认为八小时的构建过程令人难以置信,请三思。 我经常碰到这些野兽。

人们趋向于逐渐向the肿的建筑迈进,以期向团队成员提供越来越多的建筑信息。 在向开发团队提供快速反馈与从CI构建过程中提供有用信息之间,可以找到一种平衡的方法。

建立流水线以提高效率

如果您发现自己的构建过程非常耗时,并且假设您已经实施了其他持续时间改进技术(例如购买一台快速机器)并优化了测试执行时间,则可能有必要创建所谓的构建管道 。 构建管道的目的是实质上异步地执行运行时间更长的进程,以便一旦有人签入代码,就不会延迟他们收到反馈的时间。

例如,如果执行一个构建要花费10分钟以上的时间,则可以建立一个构建管道,以便在有人将代码提交到存储库中之后运行初始的轻量级构建。 这种“提交”构建由(希望)轻量级进程组成,例如编译和运行快速的单元测试。 基于该初始构建的成功,然后可以运行辅助构建,该次级构建将执行运行时间更长的测试,软件检查甚至部署到应用程序服务器。

例如,在清单3中,我配置了CruiseControl来检查存储库中的修改。 发现更改后,CruiseControl将运行所谓的委派构建,该构建将调用项目的主构建文件(例如,如果正在使用Ant,则为build.xml)。 不过,独特之处在于CruiseControl执行一个不同的目标,然后执行轻量级进程,例如编译和细粒度的单元测试。

清单3. CruiseControl配置检查修改
<project name="brewery-commit">
...
  <modificationset quietperiod="120">
    <svn RepositoryLocation="http://brewery-ci.googlecode.com/svn/trunk"/>
  </modificationset
...

在清单4中,CruiseControl配置为检查对brewery-commit项目的修改(该项目不在存储库中,它实际上是在查看日志文件)。 发现更改后,CruiseControl将运行另一个委派的构建。 该构建将调用相同的构建文件,但具有备用目标,该目标可能会执行运行时间更长的过程,例如功能测试,软件检查等。

清单4.执行长时间运行的构建的CruiseControl配置
<project name="brewery-secondary">
...
  <modificationset quietperiod="120">
    <buildstatus logdir="logs/brewery-commit" />
  </modificationset>
...

Bloated Build反模式是为什么CI不起作用的最常被引用的借口。 但是,正如您所看到的,如果您使用构建管道,则不必一定是这种方式。 有效的构建管道可最大程度地发挥“ 80/20”规则的优势:将20%的构建时间花费在会导致80%的构建错误(例如文件丢失,编译损坏和测试失败)的区域上。 此过程完成后,开发人员已收到反馈,然后运行次要的构建,可能需要更长的时间才能运行,但可能会产生其他构建错误或相对优先级的20%。

可以固定反模式

CI反模式可能会阻止团队从持续集成实践中获得最大收益; 但是,我在本文中介绍的技术可以帮助防止出现这些反模式。 您已经看到:

  • 提交代码通常可以防止将来进行复杂的集成。
  • 防止绝大多数损坏的构建就像在提交源文件之前运行私有构建一样容易。
  • 使用各种反馈机制可以防止过时的构建状态信息,否则它们将被忽略。
  • 将反馈指向可以采取行动的人员,是将团队问题告知团队成员的较好方法之一。
  • 在构建机器上花一些额外的钱值得加快对团队成员的反馈。
  • 创建构建管道是减少构建膨胀的一种技术。

我在本文中描述的反模式是我最常看到的模式,但还有其他一些模式,包括:

  • 连续无知 ,其中构建由最少的过程组成,从而始终获得成功的构建状态。
  • 该构建仅在您的计算机上有效 ,这可能会延迟从引入缺陷到修复缺陷之间的时间。
  • 瓶颈提交 ,这往往会导致构建失败并阻止团队成员回家。
  • 运行间歇性构建 ,这会延迟快速反馈。

在第2部分中 ,我将介绍其他可能阻止您从持续集成中获得最大收益的CI反模式。


翻译自: https://www.ibm.com/developerworks/java/library/j-ap11297/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值