@liuhui0803
2016-07-26T09:57:39.000000Z
字数 6043
阅读 2696
DevOps
配置管理
业务模式
ALM
源代码
摘要:
Mirco Hering讨论了为什么不能在DevOps的世界中放弃COTS产品(以及使用这些产品的人)。通过创新式解决方案可以通过自定义软件应用良好的实践,从长远角度来看这将帮助我们大幅降低工作量。
正文:
主要结论
- 对任何良好的DevOps实施来说,配置管理都是基础,是帮助我们提速的关键。
- COTS产品依然将与DevOps世界密切相关,继续为关键业务职能提供支持。
- COTS产品中的版本控制需要通过创新式解决方案找出相关代码并将其存储在源代码控制工具中。
- 通过像对待自定义代码那样对待COTS代码,将能大幅降低工作量。
- 通过四个步骤帮助COTS开发者更容易地妥善完成自己的工作,将能让DevOps世界中的COTS解决方案更易于管理。
DevOps的首要目标在于提高以可靠质量进行交付的速度。随着以更快速度进行交付时的控制程度愈加重要,良好的配置管理机制显得不可或缺(虽然骑自行车的时候你可以偶尔双手离把,但一级方程式赛车的驾驶员恨不得用胶水把手粘在方向盘上)。但是商用现货(Commercial-off-the-shelf,COTS)产品通常无法提供可供你像管理自定义软件那样进行管理的直观方式。对于需要配合使用各种技术的大企业来说,这是个切实的挑战。本文将介绍在使用COTS产品时应用现代化DevOps实践的方法。
希望本文能为打算研究如何着手的人提供一定的帮助。那么我们为什么要使用COTS和其他记录系统?
归根结底,这就是不断在说的“双传动(Two gear)”类比。如果可以直接彻底抛弃所有“遗留”应用程序,那么要恭喜你无需考虑这个问题,甚至无需继续阅读本文了。但对于做不到这一点的人,最终会意识到虽然现在已经可以用非常快的速度交付数字化和自定义的应用程序,但在某种程度上依然受制于“遗留”应用程序的桎梏。如果能加快后者的交付速度,无疑可以帮助你在交付方面实现终极速度。
例如,对于一家使用COTS产品搭建客户关系管理(CRM)系统,同时为数字化渠道(例如iPhone应用)和自己的客户服务代表(CSR)提供信息的组织来说,为iPhone应用提供新功能的速度通常会受制于后端CRM系统提供这些服务的速度。这种情况下提高CRM系统的交付速度不仅可以为iPhone应用提速,还能用更快速度为CSR提供新功能。
除了速度之外,可能还需要对这些COTS产品做大量工作才能同时支持多个代码支线(产品维护、快速发布、满足发布),而这种做法现在已经成为很多组织中很常见的模式之一。对于每个代码支线,创建分支与合并代码所需的工作量以及必要的质量保证工作量都有所增加。我曾经见过代码合并操作最多占用了20%的交付总工作量,甚至会让交付工作延后数周乃至数月。从自己的经验来说,这种合并工作可以减少最多80%,进而节约数百万美元。这个数据是对实施本文介绍的实践前后在配置管理活动方面的工作量进行对比得来的。
你可能会纳闷,COTS供应商是否知道自己需要面对更重视DevOps和持续交付的世界做好准备。在我看来,他们已经明白这一转变很重要,但这些供应商目前提供的大部分解决方案都不符合最佳实践的要求(例如定制的SCM解决方案以及开发工具API的缺乏)。下文主要内容将侧重于这样一种灰色领域:供应商希望你使用他们的解决方案,只是不鼓励你通过不被他们认可的方式使用,但实际上你想使用的方法并不会破坏解决方案进而影响到所签订的支持协议。我觉得作为社区成员,我们有责任持续督促COTS供应商采用能帮助自己更容易融入DevOps环境的技术体系结构。但整个社区的呼声还不够高,供应商会继续无视注重DevOps的组织的现实需求。
我很希望看到有供应商能主动联系我们的社区,但目前这种情况还只是奢望。业内人士需要供应商做出正确的举措,或者只能用脚投票,逐渐淘汰这样的解决方案。个人而言,在有选择并且经济方面可行的情况下,我会避免使用无法满足DevOps下列基本需求的应用程序:
在寻找实际源代码的过程中,COTS应用程序会显得非常烦人。很多此类工具自带“配置管理”机制,这类程序的供应商会尽量说服你这些机制已经很完美了。不,其实不够好,这些机制可能更适合某一应用程序,但算不上业界通用的工具。这样做也许是正确的,但问题在于:通常不可能只使用一个应用程序,同时管理多个程序配置的概率会非常大。我至今也没发现哪个专有配置管理解决方案可以轻松地与其他工具相集成。
假设有一个代码基。你希望能检索/获取所有应用程序的配置,包括源代码、参考数据、部署参数、自动化脚本。不幸的是对我来说目前通过COTS提供的配置管理工具还做不到这一切。这类产品通常并不能很好地追踪所有必要变更,主要只侧重于某部分组件。
最后同样重要的是,这类工具无法应对并行部署,也无法很好地满足有关分支与合并的需求。虽然我个人不喜欢进行分支与合并,但时不时也需要执行这样的操作。在我看来使用COTS产品实现这一切的过程会产生极高成本,同时很容易出错,但如果能对这些问题进行改进将能为用户带来一些很有意义的收益。我曾见过有组织使用Excel表格追踪记录软件版本中的模块变更,合并过程中要对这些表格进行对比,随后通过手工操作解决可能存在的冲突。这样的方式不仅易出错,而且要投入大量人力。如果能将代码存储在标准化的版本控制系统中,可将错误率降低至趋近于零,人力投入也可节约最多95%。
这家组织进行一次合并操作需要做的工作如下:
那么如果不想使用专有源代码控制工具该怎么办?首先确定应用程序所需的全部组件,最好通过某种资产管理工具来管理核心程序包及其补丁,不过本文不准备深入介绍。需要经常变更的内容则要保存在配置管理工具中。例如,在我最近实施的Siebel中,整个解决方案有超过10000个配置文件(我们曾统计过一次),但应用程序本身只有数百个文件(约为文件总数的2%)。
存储所有其他文件只会让配置管理工具变得膨胀,无法带来任何好处,因此务必要避免这样做。尤其是当你打算稍后完整提取并传输所有数据时整个过程会相当困难,信噪比也会很低。如果要衡量两个版本之间代码的变更比率,直接分析应用程序中有变更的代码,这种做法也比对整个产品的完整代码进行分析更实用。
确定所有需要追踪的组件后,可以通过多种方式处理:
选项A)使用IDE介入
效率最高,最不容易出错的方法是将开发者所用的IDE与版本控制系统在后端集成,随时拦截对COTS应用程序所做的任何变更。例如我们的某个Siebel项目使用.Net开发了少量自定义UI,并通过Siebel Tools IDE拦截对这些内容所做的全部变更,这样就可以要求开发者使用必要的元数据在版本控制系统中签入。这个UI会使用Siebel Tools IDE的临时存储找出有变更的文件,并将其推送至版本控制系统中一个预定义的位置,这样就可以避免文件位置混乱。
(注意:用手工方式在版本控制系统中存储COTS配置文件时,最终这些文件经常会出现在多个位置,这是版本控制系统的代码库文件夹结构与COTS产品不匹配所致。在重新将这些文件导入回COTS产品时,只需要注意文件名和/或文件内容,文件在文件系统中的位置并不重要。因此当无法快速确定文件是否已经位于版本控制系统内某个位置时,开发者通常会在新位置存储一个(副本)文件。通过上文提到的机制对文件位置进行控制也可以避免出现此类问题。)
下图展示的是一个自定义IDE,该IDE可支持下列功能:
图1- 能拦截任何代码改动的自定义IDE
选项B) 定期提取
如果无法与IDE轻松集成,可以使用常规提取工具从COTS应用程序中拉取配置文件,并将其推送至版本控制系统。这一过程可每晚执行一次或以更高频率进行。出于与上文选项A相同的原因,需要确定一种可以只发现最近变更内容的方法,不要每次都将每个文件推送到版本控制系统。另外很多版本控制系统会忽略完全相同副本的签入,同时整个解决方案的性能会严重受制于文件数量。
选项C) 强制在外部创建文件
几年前我使用过的一些小型COTS产品完全无法支持上述两种方式,因为IDE的UI不提供任何可编程访问的钩子,并且只提供了导入功能,不具备导出功能。这种情况下我们更改了开发过程,基本上只在COTS IDE之外进行开发,并通过自动化机制在签入版本控制系统的同时将文件导入COTS产品。这显然只是不得已而为之的方法,因为需要开发者付出额外精力,如果开发者没能遵守这种过程而使用了COTS IDE,还增加了环境中最新变更被覆盖的风险。为了使用这种方式,我们必须让部署过程实现自动化,并对整个环境进行整体控制。
很多时候依然在使用COTS或遗留应用程序的开发者并不习惯接受现代化的开发实践。强迫接受只能增加他们的负担,甚至让接受过程变得不必要的困难。应该设法让新实践变得更易于接受。
例如,不要为了让他们用你首选的配置管理系统检查代码就强迫大型机开发者将自己的文件移动到其他文件系统。
不要为了使用JIRA追踪工作项就让开发者切换上下文情境。请将额外的工具集成在开发者已经习惯的工作步骤中。例如可以使用具备基本代码检查功能的IDE(例如在COBOL中可以通过column 8启动命令),并将其与JIRA之类的工单系统集成。
对于已经习惯在基于文本的系统中进行开发的大型机开发者,通过这种方式简化获得反馈的方式也可以提高接受度。正如上文所述,在Siebel中可以通过IDE创建操作步骤,自动将代码提交至所选的配置管理系统,使得开发者更容易发现目前正在处理的工作项。
所有这些改动都有助于提高开发者对相应实践的接受度。不是因为这样做有益于整个团队,而是因为这样做可以让开发者自己的生活变得更简单。难以遵守的实践就算再好最终也只是无人问津。
就算明显的改善有时也难以实现。我曾经劝说某家公司的开发者使用IDE进行Cobol开发,不要使用文本编辑器,因为一旦代码被上传至大型机,通过后一种方式只能找出最基本的代码问题(例如命令是从column 7中启动的)。提出这个有关IDE的改进后,该团队并没有采纳,直到我证明相比其他开发者的代码,我的代码上传失败率大幅降低他们才开始认真对待。
习惯于原生COTS产品的开发者通常并不熟悉三方合并(3-way merge)。就算熟悉,传统的工具也可能无法提供必要的支持。我将会用Siebel代码演示这种情况。为了解释Siebel代码和Siebel Tools IDE的一些特征,下文将进行较为深入的介绍。
如果希望用原生方式合并代码,简单来说Siebel工具会对比文件的两个版本并显示出差异,但无法识别代码先祖(Ancestor)。随后只能由用户决定该如何处理。Siebel工具不支持三方合并。下图展示了该如何通过三方合并发现冲突。
尝试用通用的配置管理工具为Siebel提供三方合并但遇到了几个问题。开发者不信任配置管理工具。对此我觉得挺吃惊,但深入研究Siebel代码后我发现了问题所在。为了解释这个问题,首先需要展示一段代码示例:
(点击查看大图)
如图所示,Siebel会在源代码中存储一些元数据(例如用户名、变更时间戳)。在使用无法感知这一上下文情境的配置工具时,如果文件其他内容均相同,只是时间戳不同,此时会显示存在冲突。在Siebel Tools IDE中打开相同文件会发现,这个差异其实无关紧要,文件之间并不存在冲突。如果使用传统的配置管理工具,此时运行报表会看到大量误报。
这就使得用户只能使用可以避免误报,但不支持三方合并的Siebel Tools;或使用支持三方合并,但会显示大量误报的传统配置管理工具。而这也正是完善的合并工具真正的价值所在。诸如Beyond Compare等工具可以帮助用户定义能够识别代码中无需合并内容的自定义语法。用户可以为所有COTS配置定义这样的语法,并使用最适合的合并工具。
下图展示的是我的一个项目合并结果,从中可以看出需要手工介入的合并数量大幅减少。此外还针对不同类型的合并提供了分解图。
(点击查看大图)
COTS产品和其他遗留系统经常会因为人们忘了将代码签入版本控制系统而产生配置漂移问题。COTS开发者以往并不需要面对配置管理,因此发生这种情况的几率比有人未将代码放入版本控制系统就直接对环境进行更改的几率更高。这意味着应用程序或环境与目前在配置管理中存储的内容不匹配。如果出错并需要从配置管理中还原,可能会漏掉直接在环境中做出的变更。我们希望这种风险以及相应的“返工”能尽可能少。
面对配置漂移,最实际的解决方法是定期重新部署整个应用程序(最好每天进行一次,至少也要每周一次)。这样随着时间的流逝将能获得更高程度的匹配并将漂移的可能降至最低。
总而言之,只要采取恰当措施,COTS和遗留系统也能像常规的自定义代码那样管理。这意味着你可以为代码的分支与合并沿用通用实践,借此获得更可靠的环境配置,提高面对灾难事件的弹性,进而以更可预测的方式将功能交付到生产环境。
这一过程需要一些创造力,让整个开发团队实现文化观念改变的门槛略高,可一旦成功实现,将换来开发工作生产力与可预测能力的大幅提高。
在某个项目中,我们将无附加值的开发工作所占用的时间减少了超过40%。在另一个项目中,与配置有关的差错和中断减少了超过50%。如果觉得这样的效果还不够,一旦能够顺利遵循相关实践,COTS和遗留系统团队将能与其他团队开展更为紧密的合作,负责遗留系统的团队也不会感觉自己被抛弃了。
大家携手,共同迈上通往DevOps的旅程吧!
Mirco Hering负责Accenture在亚太区的DevOps和敏捷实践,主要专注于通过敏捷、DevOps、以及持续交付塑造更专业的IT组织。在使用创新式方法促进软件交付方面他有着超过10年的经验。过去几年来,Mirco主要专注于将这些方法推广至更大规模的复杂环境中。Mirco会经常在各种会议上发表演讲,并会通过他的博客分享自己的想法。
作者:Mirco Hering,阅读英文原文:How to Deal with COTS Products in a DevOps World