当前位置: 编码机 >> 编码机优势 >> DevOps核心能力技术篇代码可维护
DevOps技术:代码可维护性
运行我们构建的系统需要大量代码:Android操作系统运行到万行代码,Google的单一代码库包含超过10亿行代码,典型的智能手机应用包含50,行代码。
基于DevOps研究和评估组织(DORA)研究的年DevOps现状报告表明,团队有效维护代码的能力是众多可积极促成持续交付取得成功的技术实践之一。
如果您的团队在代码可维护性方面表现良好,则满足以下条件:
团队可轻松在代码库中找到示例,重复使用其他人的代码,并在必要时更改其他团队维护的代码。团队可以轻松地将新的依赖项添加到其项目,以及迁移到新的依赖项版本。团队的依赖项稳定,并且很少破坏代码。这些发现结果突显了开发者可轻松地在整个组织的代码库中找到、重复使用和更改代码,以及实现相关实践和工具来帮助依赖项管理的重要性。
代码可维护性是一项需要组织范围协调的功能,因为它依赖于能够搜索、重复使用和更改其他团队的代码。有效管理依赖项通常是在使用大型代码库和应对大型组织时遇到的主要难题。有助于避免依赖项出现问题或说明代码更改后果的工具可以为所有工程师改进设计决策和代码质量,从而有助于他们提高工作速度并打造更稳定可靠的软件。
如何实现代码可维护性
就实现而言,虽然可以分开进行源代码管理和依赖项管理,但一个解决方案(例如单一代码库或Google使用的monorepo模式)可以同时解决这两个问题。
首先,源代码管理。如果让每个人都可以轻松找到、重复使用和建议对代码库的任何部分进行更改,那么就可以:
加快交付:为了快速交付软件,团队需要能够查看和建议对彼此代码的更改。尽早执行此操作有助于在整个组织内传播知识,并且有助于将需要更改代码库其他部分的团队取消屏蔽,以便他们完成工作。提高稳定性和可用性水平:如果发生突发事件,能够快速找到并建议对代码库任何部分的更改至关重要。提高代码质量:重构代码以提高内部质量,通常需要更改代码库的多个部分。如果这样做很困难,则会降低人们执行重构的可能性,也会增加这样做的费用。一些组织(包括Google)运行跨团队代码维护项目,其中个人负责在代码库中修复维护级层项,而这依赖于可以在组织中轻松访问和更改代码。能够找到示例并重复使用其他人的代码取决于能够轻松访问和搜索整个组织的源代码。实现此要求的最简单方法是针对整个组织的代码使用单个版本控制平台,即使该代码在平台内拆分为多个代码库也是如此。使用的版本控制平台越分散,就越难找到代码。
某些组织可能希望锁定代码库部分,以便只有需要知道的人才能查看该代码库的该部分(Google就是这样的组织)。理想情况下,这应该是例外(而非规则),并且应将软件设计为可最大限度地减少机密源代码表面。在很多情况下,使用版本控制系统的访问权限控制机制对机密代码进行逻辑隔离就足够了。
您还应能够更改其他团队维护的代码。通常,此类更改将需要获得负责维护相关代码的团队批准。如果使用拉取请求(即在版本控制中创建分支和批准导致合并分支)等机制,可最大限度地减少允许其他团队建议更改的摩擦,同时也可防止未经授权的更改,并强制执行信息安全控制(例如职责分离)。
接下来,考虑依赖项。让团队能够轻松添加和更新依赖项,并确保它们稳定且很少破坏代码,这意味着:
提高安全性:随着依赖项老化,就越有可能发现漏洞。保持依赖项最新很重要,特别是在发现并修补漏洞之后。加快交付:使用其他团队或组织开发的库意味着您无需编写自己的代码即可执行该操作。当您部署了一些机制来确保依赖项稳定并很少破坏代码后,可以将更多时间花在编码上,缩短维护时间。依赖项管理是软件开发团队的常见痛点。在应用之间保持依赖项最新和一致很复杂、耗时且成本高昂。许多组织无法为此任务分配足够的资源,这一问题因流程和工具不足而加剧。当在依赖项中不可避免地发现漏洞时,这可能表示严重的安全风险,并且必须更新使用依赖项的应用。
务必采用并改进相关流程和工具,让团队能够轻松使用已知良好的依赖项版本并快速升级这些依赖项,包括自动化持续集成(CI)和测试,以发现新版本的依赖项是否包含破坏性更改,并快速且简单地将正在使用的依赖项的版本与使用这些版本的系统相关联。
在软件中添加依赖项时有两种常用的模型:vendoring和声明式清单。在vendoring中,会将每个依赖项的源代码或二进制文件随应用一起签入版本控制中。或者,大多数现代平台都有一个依赖项管理工具,用于管理签入版本控制的声明式清单文件中指定的依赖项(例如Python的pip、Node.js的npm、R的CRAN和.NET的NuGet)。
无论您是使用vendoring还是使用清单,最重要的注意事项都是:
可追溯性:确保您可以从任何给定的软件包或部署追溯到用于构建它的每个依赖项的确切版本。否则,将无法调试因依赖项更改而导致的问题。可再现性:您的构建过程应尽可能具有确定性。尝试调试在不同机器上具有不同行为的构建过程引发的问题非常困难。在Google中实现代码可维护性
Google通过相对不同的方法实现代码可维护性。虽然我们的方法需要权衡利弊,且并非适合所有人,但这样做可以有效地让团队实现本文中所述的目标。
全球有95%的Google软件开发者使用主干开发模型,处理通过集中式源代码控制系统维护的共享单一代码库。年,Google代码库包含“大约10亿个文件,其中包括Google成立18年以来大约万次提交的历史记录。该代码库包含86TB的数据,其中包括大约20亿行代码,分布在万个唯一源代码文件中”。
由于所有Google代码都保存在一个代码库中,因此可以轻松找到和更改其他团队的代码。Google提供内部搜索引擎,使您可以轻松地搜索整个代码库。开发者可通过各种工具创建更改列表以供审核和批准。系统会针对每个更改列表运行测试,并且可以对更改列表进行更新和评论。与许多其他平台类似,Google的代码审核工具可以向审核者建议任何给定更改。Google代码库中的每个目录都有一个OWNERS文件,其中列出了可以批准该目录中的文件更改的个人或组(类似功能在GitHub、GitLab和Bitbucket中有提供)。快速搜索、审批者建议和自动化测试,使得建议更改、审核和协作变得简单而强大。
借助这些工具,更改代码库多个部分的大规模重构相对容易执行并且能够以原子方式完成。Google构建的工具可进一步简化和自动化执行会影响代码库重要部分的更改的过程。Google工具包含一个名为Blaze的构建系统,用于构建和测试来自源代码的任何更改,包括依赖项。(Blaze部分以开源工具Bazel的形式发布。)Google中的每个人都可以轻松发现并建议对Google的任何部分进行更改,包括其基础架构配置,这些配置也保存在同一单一代码库中。代码共享和重复使用很简单。
Google提供了一些控制措施来管理开源软件的依赖项。首先,Google使用的所有开源软件都必须将其源代码签入Google单一代码库。其次,任何时候都只能将给定库的一个版本签入源代码控制。第三,所有软件都是静态链接并基于源代码构建。最后,只要库的源代码发生更改,就会触发所有使用该依赖项的软件的重新构建和自动化测试。
通过这些控制措施及Google强大的CI基础架构,您可以轻松让生产系统保持最新状态,并确保使用新版本的依赖项。它们还有助于确保所有系统都使用给定库的一致版本(消除了“钻石依赖项”地狱的可能性,即产品依赖于两个组件,而这些组件又依赖于不同版本的通用库,使得无法构建产品。)
Google管理外部代码依赖项的的方法权衡是更难以添加新依赖项(代码可维护性的主要结果之一)。任何新依赖项都必须将其源代码签入Google单一代码库,这意味着,在最初和任何升级时,都必须先审核和测试代码。但是,这种严谨级别有助于防止将存在安全漏洞的代码放入Google产品,并确保所有依赖项也明确指定了维护者。
实现代码可维护性的常见误区
让所有人都可以全面搜索和更改所有代码的主要障碍是工具支持和组织文化。
第一个常见误区是多个版本控制代码库或具有严格访问权限设置的版本控制代码库。理想情况下,组织应该有一个版本控制平台,其中包含所有代码。默认访问权限最好允许组织中的任何人查看任何源代码文件,并且可以限制对敏感文件的访问。还应有一种方法来搜索版本控制。
相比之下,组织通常限制谁可以更改版本控制。这会导致第二个误区:缺少工具和流程,导致用户无法更改代码库中自身没有写入权限的部分。对于解决您依赖其代码的其他团队通常无意中造成的问题,这通常是一个重大障碍。这也会阻止涉及代码库多个部分的重构。
为了缓解此问题,一些现代版本控制工具提供了一种方法来提交、复核、审批和审核代码库中用户没有写入权限的部分的更改请求。
即使提供工具支持,组织也需要对在组织内提供和搜索代码库放心,甚至也对供应商和承包商放心。如果组织的版本控制代码库包含大量机密信息和不能在团队之间共享的代码,则可能无法实现这一点。
使用二进制文件依赖项更为常见,但每种语言都有各自用于管理二进制依赖项的工具链。创建标准策略和惯例以在组织的整个软件产品组合中跨这些工具链有效地管理和跟踪依赖项是一项复杂的工作。需要对CI基础架构进行重大投资,让您可以轻松测试新版本的库是否与现有系统兼容,以及是否有漏洞,才能简化定期升级第三方库的流程。
实际上,大多数组织都会让团队来管理依赖项,导致结果差异很大。因此,如果在库中发现漏洞,快速且可预测地做出响应通常是非常麻烦的:即使找到受影响的服务通常也是一个重大的考古项目。
如何衡量代码可维护性
下面是一些有助于衡量代码可维护性的简单方法:
贵组织的代码库有多少百分比是可搜索?要更改我没有写入权限的代码库部分,中位数完成时间是多少?我们的代码库有多少百分比是重复代码?未使用的百分比是多少?在使用的所有库中,有多少百分比的应用未使用最新的稳定版本?我们在生产环境中具有每个库的多少个不同版本?中位数是多少?良好的目标是什么?有多少个版本超过1年?团队升级其库的频率如何?这需要多长时间?在考虑要衡量的项目时,有三个用例需要重点
转载请注明:http://www.aideyishus.com/lkgx/1718.html