写点什么

在 DevOps 的世界中如何面对 COTS 产品

2016 年 8 月 01 日

主要结论

  • 对任何良好的 DevOps 实施来说,配置管理都是基础,是帮助我们提速的关键。
  • COTS 产品依然将与 DevOps 世界密切相关,继续为关键业务职能提供支持。
  • COTS 产品中的版本控制需要通过创新式解决方案找出相关代码并将其存储在源代码控制工具中。
  • 通过像对待自定义代码那样对待 COTS 代码,将能大幅降低工作量。
  • 通过四个步骤帮助 COTS 开发者更容易地妥善完成自己的工作,将能让 DevOps 世界中的 COTS 解决方案更易于管理。

DevOps 的首要目标在于提高以可靠质量进行交付的速度。随着以更快速度进行交付时的控制程度愈加重要,良好的配置管理机制显得不可或缺(虽然骑自行车的时候你可以偶尔双手离把,但一级方程式赛车的驾驶员恨不得用胶水把手粘在方向盘上)。但是商用现货(Commercial-off-the-shelf,COTS)产品通常无法提供可供你像管理自定义软件那样进行管理的直观方式。对于需要配合使用各种技术的大企业来说,这是个切实的挑战。本文将介绍在使用 COTS 产品时应用现代化 DevOps 实践的方法。

COTS 产品将成为不断向前迈进的企业环境中不可或缺的一部分

希望本文能为打算研究如何着手的人提供一定的帮助。那么我们为什么要使用 COTS 和其他记录系统?

归根结底,这就是不断在说的“双传动(Two gear)”类比。如果可以直接彻底抛弃所有“遗留”应用程序,那么要恭喜你无需考虑这个问题,甚至无需继续阅读本文了。但对于做不到这一点的人,最终会意识到虽然现在已经可以用非常快的速度交付数字化和自定义的应用程序,但在某种程度上依然受制于“遗留”应用程序的桎梏。如果能加快后者的交付速度,无疑可以帮助你在交付方面实现终极速度。

例如,对于一家使用 COTS 产品搭建客户关系管理(CRM)系统,同时为数字化渠道(例如 iPhone 应用)和自己的客户服务代表(CSR)提供信息的组织来说,为 iPhone 应用提供新功能的速度通常会受制于后端 CRM 系统提供这些服务的速度。这种情况下提高 CRM 系统的交付速度不仅可以为 iPhone 应用提速,还能用更快速度为 CSR 提供新功能。

除了速度之外,可能还需要对这些 COTS 产品做大量工作才能同时支持多个代码支线(产品维护、快速发布、满足发布),而这种做法现在已经成为很多组织中很常见的模式之一。对于每个代码支线,创建分支与合并代码所需的工作量以及必要的质量保证工作量都有所增加。我曾经见过代码合并操作最多占用了 20% 的交付总工作量,甚至会让交付工作延后数周乃至数月。从自己的经验来说,这种合并工作可以减少最多 80%,进而节约数百万美元。这个数据是对实施本文介绍的实践前后在配置管理活动方面的工作量进行对比得来的。

不幸的是,很多 COTS 产品尚未准备好进入 DevOps 的世界

你可能会纳闷,COTS 供应商是否知道自己需要面对更重视 DevOps 和持续交付的世界做好准备。在我看来,他们已经明白这一转变很重要,但这些供应商目前提供的大部分解决方案都不符合最佳实践的要求(例如定制的 SCM 解决方案以及开发工具 API 的缺乏)。下文主要内容将侧重于这样一种灰色领域:供应商希望你使用他们的解决方案,只是不鼓励你通过不被他们认可的方式使用,但实际上你想使用的方法并不会破坏解决方案进而影响到所签订的支持协议。我觉得作为社区成员,我们有责任持续督促 COTS 供应商采用能帮助自己更容易融入 DevOps 环境的技术体系结构。但整个社区的呼声还不够高,供应商会继续无视注重 DevOps 的组织的现实需求。

我很希望看到有供应商能主动联系我们的社区,但目前这种情况还只是奢望。业内人士需要供应商做出正确的举措,或者只能用脚投票,逐渐淘汰这样的解决方案。个人而言,在有选择并且经济方面可行的情况下,我会避免使用无法满足 DevOps 下列基本需求的应用程序:

  • 所有源代码、配置和数据能够提取出来并集中存储在外部版本控制系统中吗?
  • 构建、编译、部署和配置所要触发应用程序的所有必要步骤可通过 API(基于可编程语言的 CLI)实现吗?
  • 所有环境配置可以暴露至文件中,并以编程的方式操作吗?

我是如何实现“可编码”COTS 并控制其配置管理工作的?

第 1 步 – 找到源代码

在寻找实际源代码的过程中,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,还增加了环境中最新变更被覆盖的风险。为了使用这种方式,我们必须让部署过程实现自动化,并对整个环境进行整体控制。

第 2 步 – 让开发者更容易接受好的实践

很多时候依然在使用 COTS 或遗留应用程序的开发者并不习惯接受现代化的开发实践。强迫接受只能增加他们的负担,甚至让接受过程变得不必要的困难。应该设法让新实践变得更易于接受。

例如,不要为了让他们用你首选的配置管理系统检查代码就强迫大型机开发者将自己的文件移动到其他文件系统。

不要为了使用 JIRA 追踪工作项就让开发者切换上下文情境。请将额外的工具集成在开发者已经习惯的工作步骤中。例如可以使用具备基本代码检查功能的 IDE(例如在 COBOL 中可以通过 column 8 启动命令),并将其与 JIRA 之类的工单系统集成。

对于已经习惯在基于文本的系统中进行开发的大型机开发者,通过这种方式简化获得反馈的方式也可以提高接受度。正如上文所述,在 Siebel 中可以通过 IDE 创建操作步骤,自动将代码提交至所选的配置管理系统,使得开发者更容易发现目前正在处理的工作项。

所有这些改动都有助于提高开发者对相应实践的接受度。不是因为这样做有益于整个团队,而是因为这样做可以让开发者自己的生活变得更简单。难以遵守的实践就算再好最终也只是无人问津。

就算明显的改善有时也难以实现。我曾经劝说某家公司的开发者使用 IDE 进行 Cobol 开发,不要使用文本编辑器,因为一旦代码被上传至大型机,通过后一种方式只能找出最基本的代码问题(例如命令是从 column 7 中启动的)。提出这个有关 IDE 的改进后,该团队并没有采纳,直到我证明相比其他开发者的代码,我的代码上传失败率大幅降低他们才开始认真对待。

第 3 步 – 支持智能合并

习惯于原生 COTS 产品的开发者通常并不熟悉三方合并(3-way merge)。就算熟悉,传统的工具也可能无法提供必要的支持。我将会用 Siebel 代码演示这种情况。为了解释 Siebel 代码和 Siebel Tools IDE 的一些特征,下文将进行较为深入的介绍。

如果希望用原生方式合并代码,简单来说 Siebel 工具会对比文件的两个版本并显示出差异,但无法识别代码先祖(Ancestor)。随后只能由用户决定该如何处理。Siebel 工具不支持三方合并。下图展示了该如何通过三方合并发现冲突。

(点击放大图像)

尝试用通用的配置管理工具为 Siebel 提供三方合并但遇到了几个问题。开发者不信任配置管理工具。对此我觉得挺吃惊,但深入研究 Siebel 代码后我发现了问题所在。为了解释这个问题,首先需要展示一段代码示例:

(点击放大图像)

如图所示,Siebel 会在源代码中存储一些元数据(例如用户名、变更时间戳)。在使用无法感知这一上下文情境的配置工具时,如果文件其他内容均相同,只是时间戳不同,此时会显示存在冲突。在 Siebel Tools IDE 中打开相同文件会发现,这个差异其实无关紧要,文件之间并不存在冲突。如果使用传统的配置管理工具,此时运行报表会看到大量误报。

这就使得用户只能使用可以避免误报,但不支持三方合并的 Siebel Tools;或使用支持三方合并,但会显示大量误报的传统配置管理工具。而这也正是完善的合并工具真正的价值所在。诸如 Beyond Compare 等工具可以帮助用户定义能够识别代码中无需合并内容的自定义语法。用户可以为所有 COTS 配置定义这样的语法,并使用最适合的合并工具。

下图展示的是我的一个项目合并结果,从中可以看出需要手工介入的合并数量大幅减少。此外还针对不同类型的合并提供了分解图。

(点击放大图像)

第 4 步 – 通过强制应用的正确配置实现闭合环路(即完整部署)

COTS 产品和其他遗留系统经常会因为人们忘了将代码签入版本控制系统而产生配置漂移问题。COTS 开发者以往并不需要面对配置管理,因此发生这种情况的几率比有人未将代码放入版本控制系统就直接对环境进行更改的几率更高。这意味着应用程序或环境与目前在配置管理中存储的内容不匹配。如果出错并需要从配置管理中还原,可能会漏掉直接在环境中做出的变更。我们希望这种风险以及相应的“返工”能尽可能少。

面对配置漂移,最实际的解决方法是定期重新部署整个应用程序(最好每天进行一次,至少也要每周一次)。这样随着时间的流逝将能获得更高程度的匹配并将漂移的可能降至最低。

结论

总而言之,只要采取恰当措施,COTS 和遗留系统也能像常规的自定义代码那样管理。这意味着你可以为代码的分支与合并沿用通用实践,借此获得更可靠的环境配置,提高面对灾难事件的弹性,进而以更可预测的方式将功能交付到生产环境。

这一过程需要一些创造力,让整个开发团队实现文化观念改变的门槛略高,可一旦成功实现,将换来开发工作生产力与可预测能力的大幅提高。

在某个项目中,我们将无附加值的开发工作所占用的时间减少了超过 40%。在另一个项目中,与配置有关的差错和中断减少了超过 50%。如果觉得这样的效果还不够,一旦能够顺利遵循相关实践,COTS 和遗留系统团队将能与其他团队开展更为紧密的合作,负责遗留系统的团队也不会感觉自己被抛弃了。

大家携手,共同迈上通往 DevOps 的旅程吧!

关于本文作者

Mirco Hering负责 Accenture 在亚太区的 DevOps 和敏捷实践,主要专注于通过敏捷、DevOps、以及持续交付塑造更专业的 IT 组织。在使用创新式方法促进软件交付方面他有着超过 10 年的经验。过去几年来,Mirco 主要专注于将这些方法推广至更大规模的复杂环境中。Mirco 会经常在各种会议上发表演讲,并会通过他的博客分享自己的想法。

查看 **** 英文原文:How to Deal with COTS Products in a DevOps World

2016 年 8 月 01 日 18:28911
用户头像

发布了 283 篇内容, 共 84.6 次阅读, 收获喜欢 34 次。

关注

评论

发布
暂无评论
发现更多内容

架构师训练营作业(6周)

邵帅

天猫小店、京东小店的问题分析

石云升

价值网络 新零售 天猫小店

并发业务中,线程安全与否很重要,来看看你懂多少?

Java小咖秀

Java 多线程与高并发

我学会了用Python预测股票价格

博文视点Broadview

Python 读书笔记 算法 数据分析

探秘 Spring 的 PropertyEditor

CoderLi

Java spring 后台

上亿数据怎么玩深度分页?兼容MySQL + ES + MongoDB

Kerwin

Java MySQL ES 深度分页

Redis进阶篇二——持久化

多选参数

redis redis6.0.0 redis集群 redis持久化

架构师训练营(6周)

邵帅

职业发展的迷茫与困境:你真的了解职级体系吗?

伴鱼技术团队

技术管理 人才培养 程序员成长 职业成长 技术人生

Apache Flink 是什么?

Apache Flink

flink

CAP 原理

Z冰红茶

朱嘉明:区块链对深入改革的意义何在?

CECBC区块链专委会

区块链技术 政策扶持 块链与经济 区块链功能 产业数字化

JVM详解之:java class文件的密码本

程序那些事

Java JVM class GC 密码

rdd序列化

InfoQ_6cf02607664f

GaussDB for DWS:内存自适应控制技术总结

华为云开发者社区

大数据 数据湖 内存管理 sql 华为云

「1.4万字」玩转前端 Video 播放器 | 多图预警

阿宝哥

前端 流媒体 Video播放器 HLS

【week06】作业

chengjing

图解:有向环、拓扑排序与Kosaraju算法

淡蓝色

Java 数据结构 算法

程序员的眼界真的不要,也不能只局限于技术

非著名程序员

极客时间 程序员 提升认知 程序员成长

Doris 临时失效 UML 时序图(训练营第六周)

看山是山

Doris

负载均衡

满山李子

【week06】总结

chengjing

架构师训练营第六周

大丁💸💵💴💶🚀🐟

我在阿里积累到的撰写数据分析报告经验

DeeperMan

大数据 数据分析 数据可视化

最右JS2Flutter框架——渲染机制(二)

刘剑

flutter 前端 跨平台 探索与实践

NOSQL - 第六周作业

孙志平

MySQL 高可用和分布式数据库(训练营第六课)

看山是山

zookeeper CAP 主从复制 主主复制 MySQL 高可用

Java这么优秀,我当然要深入啦

程序员小跃

Java Lambda

C、C++、Java到Python,编程入门学习什么语言好?

华为云开发者社区

c c++ Python 编程语言 Java 分布式

week6 学习总结 Nosql

Z冰红茶

计算机网络基础(三)---网络层-IP协议的转发流程

书旅

php laravel 网络协议 计算机基础 网络层

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

在DevOps的世界中如何面对COTS产品-InfoQ