转载

工程师如何选择开源软件?

编者按本文节选自《工程师如何对待开源》,作者谭中意是星策开源社区发起人、中国开源推进联盟副秘书长,同时也是在知名科技企业从事开源相关工作超过 20 年的工程师,亲身经历或者亲眼目睹很多工程师开源领域的优秀实践,同时也看到了很多 Bad Cases工程师如何对待开源》一文凝聚作者诸多心得和体会除了本文所呈现的“工程师如何选择开源软件的内容之外,还着重阐述了“工程师如何定制和维护开源软件”“工程师个人成长如何利用开源两个话题。谭中意说:“希望能帮助工程师更好成长。 

作者:星策开源社区发起人、中国开源推进联盟副秘书长 谭中意

作为技术工程师,工作任务就是用技术手段支持和实现公司所关注的商业目标。 实际工作中,主动或者被动使用和维护大量开源软件。 据统计,每个工程师在企业内部进行研发和运维等工作的时候,每年会接触到上千款开源软件, 如果是以Java或JavaSciprt 为主要程序开发语言的工程师,则接触到的开源软件数量更多,在万级别甚至十万级别。 数据来源:《2020 State of the Software Supply Chain》由 Sonatype 发布

那么如何选择开源软件? 这么多开源软件中,如何根据个人需求和业务需要来选择合适的开源项目进行投入

首先要明确对开源软件的态度,在现阶段开对开源软件的使用。不过,使用开源软件会面临各种各样的风险,包括开源合规、安全、效率问题。 简化为一句:在企业内部高效、安全、合规使用开源软件,需要遵守该企业对开源软件的内部规定,包括如何引入和如何维护

回到具体如何选择特定的开源软件的问题上,有如下几个纬度可以进行参考。

  • 根据需求
  • 根据技术发展趋势
  • 根据软件采纳周期的不同阶段
  • 根据开源软件的成熟度情况
  • 根据项目的质量指标
  • 根据项目的治理模式

一、根据需求来选择开源软件

选择开源软件,首先要明确需求,即选择这个开源软件的目的究竟是什么是用来进行个人学习的; 还是用来满足 to B客户的需求的;是用来满足内部服务开发的需求的。 因为不同的目的,选择开源软件的导向完全不一样。(注意:后两个场景需要先考虑企业开源合规的需求,参考各个企业内部开源合规要求

进行个人学习

先说说选择开源软件来进行个人学习,那么要看学习的具体目的究竟是什么。 是想学习一种比较流行的技术来完善个人的技术知识结构扩大个人技术视野;还是想看看相应的开源技术项目的具体实现,来作为内部项目技术开发的参考;还是想为了下一份工作有针对性进行技术准备。

针对前者,显然是什么技术最流行选什么,自己缺什么选什么;针对第二种目的,一般是对该技术领域的知名开源软件或创新性软件针对性地进行选择,即某个特性是我当前需要的,或者是我当前项目实现不好的,我需要看看别人是如何实现的。最后一种,显然是按照下一份工作的职位需要和技术栈要求进行准备,并根据技术栈要求的门槛高低进行选择。

但是注意,从个人需求出发选择开源软件,一般都需要写个小项目练练手,比如一个 Demo 程序或者一个测试服务,因为不用考虑后续的长期维护,所以尽可以按照个人的想法和个人研发习惯进行各种练习,不用遵循企业内部的开发流程和质量要求,也不用考虑该开源软件的稳定性和社区成熟度等情况,只需要尽情学习和参考代码就好了。

满足 to B 客户的需求

选择开源软件进行研发的软件是需要提供给客户的,往往可能是以私有云的方式进行交付。基于此类需求来选择开源软件,注意好平衡,即要平衡好客户的需求和企业自身技术规划或产品的长期规划需要。

以私有云方式进入客户的 IDC 环境,是需要跟客户开发和运行环境的上下游项目进行集成的。这时候要看客户的需要,可能某些客户对开源软件有特定的要求,例如要求使用 HDFS 而且是某个特定版本。客户之所以会指定软件名字和指定版本,可能是因为当前比较熟悉这个版本,也有可能是因为之前其他软硬件供应商提供的软件和版本,指定的目的是方便集成和后续的使用与维护。

如果这种需求是符合企业项目或者产品的长期发展需求的,则是可以完全满足的。如果甲方非常强势,除了满足他的要求之外没有别的办法,那就选择客户所指定的软件和版本好了。

但如果跟自身项目或产品的长期发展需求不一致,而且具体项目或者版本是可以跟甲方进行协商的,那么需要跟客户协商出一个双方都能接受的结果,即选择特定的开源软件和版本既要做到客户满意并买单,又要做到自身的交付成本可控,还要做到符合自身项目或者产品的长期发展需要。

例如客户使用 Java 的某个老版本,但是企业的 to B 交付的软件要求使用 Java 的较高版本。那么需要跟客户协商,要么切换到企业希望的版本上,还需要帮助客户完成已有系统的升级工作;要么只能降低自身软件的 Java 版本需求,可能还需要对某些自身代码进行修改,还可能对软件中的某些依赖组件进行修改。这个场景下是带有很多客观约束条件下的选择,是需要跟客户,自身的产品经理和架构师一起协商的。

满足内部服务需求

如果场景是为了满足内部服务的需求,即选择开源软件来搭建的服务是给内部业务或者最终用户来使用的,常见于国内各大互联网公司的互联网服务系统和各种手机上的 App。这时候项目的开发和维护方有较大的自主权,跟 to B的交付业务完全不一样。此时选择开源软件,就一定要综合考虑开发和维护成本,还要考虑使用该服务的业务所处的阶段。

1如果提供的服务是给创新业务使用的,创新业务一般都是试错业务,随时需要根据市场情况的变化和当前执行的状态进行调整,很可能三个月后这个项目没了,即被取消了。这种情况下 “糙快猛” 的开发方式是比较合适的,不用太多考虑系统的可维护性和可扩展性,就用研发团队最熟悉的软件技术栈,然后用底层技术支撑团队比如基础架构团队提供的成熟而且经过验证后的底层基础技术平台就可以,最重要是尽快把系统搭建出来,然后随着产品进行快速的迭代。

这个时候需要尽量降低现有研发运维团队的学习成本和开发成本,不用太多考虑可维护成本,因为需要糙快猛的把系统堆出来,验证产品需求和商业模式是最重要的,时间最重要。如果发现有市场机会,就快速跟进,站稳脚跟之后可以采用省时间但是费资源的方式(俗称 “堆机器”)来进行扩展,或者采用 “边开飞机边换引擎” 的模式进行重写都是比较划算的。对于处于创业阶段的企业或者项目来说,速度胜过一切。

2如果选择开源软件搭建出来的计算机软件系统或者服务需要长期维护,比如是给公司内成熟业务使用的,或者是针对公司内成熟平台的缺点进行系统升级并要替代原有产品的,那么在满足业务需求的前提下,考虑系统的可维护性变成最重要的事情。

选择对应的开源软件,它是否成熟,是否稳定;二次开发是否友好;运维成本是否比较合算即比较省机器和带宽;运维操作是否方便,例如常见的扩容和缩容操作是否可以高效、自动、无损的完成;Upstream 到上游开源社区是否容易等等,这些都成为需要重点考虑的事情。这种情况下,开发一个系统的成本,可能只占整个系统生命周期内的成本的 1/10 不到。所以在满足需求的前提下,重点考虑可维护性。

二、 根据技术发展趋势来选择开源软件

如上图所示,现代计算机软件或者服务的研发,是一个不断运行的循环和迭代过程。从市场分析开始,然后进入到创意阶段,再到编码阶段,最后到上线阶段完成应用的部署和生效,上线之后根据得到的数据反馈,继续进行分析。

这个循环迭代的过程,显然对于一个身处行业竞争激烈的企业来说,迭代的速度越快越好,同时也需要具备快速弹性、低成本伸缩的能力,即产品方向对了,那么赶紧进行系统扩容,承接快速增长的流量,做到快速增长;如果产品方向不对,需要赶紧缩容,把相关硬件和人力资源节省出来,投入到新的试错方向上去。身处同一个行业内的企业,如果企业 A 能以更低的成本,更快的速度进行各种产品和策略的迭代,显然它比迭代速度慢,成本高的企业 B 更具有竞争优势。

现在的开源软件数量非常多,几乎每一个分类下面都有很多的开源项目。针对某一个具体的需求,如何进行选择?一个建议是根据技术趋势进行选择。即现在的计算机系统迭代的方式是 Agile(敏捷) + Scale(扩展)。

显然,能够支持计算机系统进行快速迭代,并能够很方便进行低成本弹性伸缩的开源软件值得进行长期投入。而对一个新的开源软件的学习和使用,学习者是希望该软件的学习门槛越低越好。一个流行的开源软件,内部实现可以尽可能复杂,但是对于用户来说一定是需要用户友好的。不然即使创新度再好,易用性不好,只有极客才能学习和掌握,创新的鸿沟很难跨越。

例如 Docker 的出现之后,以极快的速度风靡全球之所有非常多的工程师喜欢 Docker就是因为 Docker 的特性——在传统的容器系统之上增加了新特性,包括把应用程序和底层依赖库封装为一个容器镜像,容器镜像有版本,而且可以通过集中的镜像仓库进行存储和大批量分发。

Docker 首先解决了长期困扰工程师的开发、测试、上线环境标准化的问题,能够支持开发者进行快速的迭代。同时使用了统一的镜像仓库来进行镜像的分发,而且底层采用了轻量级虚拟机即容器的技术,可以非常快被拉起,所以采用 Docker 的系统可以很方便进行弹性扩展。同时,因为把应用 App 封装在一个镜像里面,可以在逻辑上根据 Domain Model的设计原则进行更好抽象和复用。

显然,这样的技术值得每一个开发计算机系统的工程师学习和掌握。因为他能带来极大的方便。

相反,在 Docker 产生之前,虽然 Control Group(简称 cgroup) + Namespace 的技术早就已经出现,并早就集成在 Linux 内核中,Google 的 borg 相关的论文早就已经发表,但是一般的技术研发团队不是很容易就能驾驭容器并把容器系统在公司内部大规模进行部署的。

印象中 borg 论文出现后,国内只有 BAT 级别的互联网公司,才有一小撮精英研发团队来研发和使用容器管理系统,例如百度负责 Matrix 系统研发的团队,阿里负责 Pounch 系统研发的团队,腾讯也有一个小团队负责容器系统的研究。

但是除了那一小部分团队,更多的工程师因为学习难度较大而没有把容器大批量地用起来。而Docker这种技术,非常好顺应了敏捷和弹性扩展的技术趋势,而且提供了非常好的用户易用性,一出场就被非常多的工程师迅速使用,而且成为市场的默认标准。

这些顺应潮流的开源软件是值得选择和投入的。

另外一个例子是 Spark,Spark 的出现解决了 MapReduce 在分布式计算过程中因为需要频繁进行 IO 操作导致的性能比较低下的问题,同时在易用性上有较大的提升,所以才取代了 MapReduce 在分布式计算领域内的主流地位。

三、根据开源软件采纳周期的不同阶段进行选择

软件作为智力活动的产物,有它自己的生命周期,一般用软件的技术采纳曲线表示。

开源软件也是软件的一种,也都遵循软件的技术采纳规律。如下图所示

一个开源软件从创建到衰亡一般会经过 5 个阶段。 从创新期(Innovators,占比 2.5%),到早期采纳期(Early Adopters,占比 13.5%),然后跨越鸿沟(chasm),进入到早期大众期(Early Majority,占比 34%),再进入后期大众期(Late Majority,占比 34%),最后进入衰退期(Laggards,占比 16%)。

绝大部分的开源创新项目,没能成功的跨域鸿沟,即从早期采纳阶段进入到早期大众阶段,就消亡了。 所以,如果是选择一个需要长期使用并维护的开源项目,选择处于早期大众或者后期大众状态的项目是比较理智和科学的。

当然如果只是个人想学习一个新的东西,可以看看处于创新者状态的开源项目,或者看看处于 “早期采纳者” 状态的项目。

注意不管是从长期研发系统的角度,还是从个人学习的角度,都不要再去看处于衰退期(Laggards)的项目了。 例如现阶段即 2022 年,是不用再去选择 Mesos,Docker Swarm 之类的项目了。自从 Kubernetes 成为容器调度技术分类的默认标准,这两个项目就已经处于衰退期,他们的母公司都已经放弃了。这个阶段如果还投入较多精力来开发和维护,除非真的是非常强势的甲方要求,把钱砸在工程师面前得他们不得不用。

同学们可能会问,从哪里可以看到这些技术采纳度曲线?InfoQgartnerthoughtworks 每年都会更新他们各自的技术采纳度曲线并公布出来,可以 根据这些曲线,再结合一些业内的经验,得出自己的判断。

从2022 年 InfoQ 对 BigData 领域各种流行技术的判断来看,Hudi、Clickhouse、Delta Lake 等开源软件还处于创新者的阶段,即在工业界采纳还比较少,想学习新项目的同学可以重点关注。但是现在这些开源软件还不适合应用在需要长期维护的成熟应用场景里面。

注意这些知名科技媒体的技术采纳曲线是每年都在更新的,在进行参考的时候别忘了注意一下发表的时间。

2022 年 InfoQ 对 BigData 领域各种流行技术的判断

四、根据开源软件的成熟度情况选择开源软件

还有一点,即根据开源软件本身的成熟度来选择开源。 即从这个开源软件是否定期发布,是否处于一个多方维护的状态(即使一个公司的战略发生了变化不再继续维护了,还有其他的公司在长期支持),是否文档比较齐全等多个维度来进行成熟度的评估。

对于开源软件的成熟度模型,开源社区有很多度量开源项目的成熟度模型,其中 Apache 开源软件基金会的项目成熟度模型是比较有名的把一个开源项目的评估纬度,分为 7 个维度:

  • Code(代码)
  • License and Copyright(软件许可证和版权)
  • Release(发布)
  • Quality(质量)
  • Community(社区)
  • Consensus Building(共识共建)
  • Independence(独立性)

每个纬度又有几个考察项。例如针对 Independence(独立性),又有两个考察项,其一是看这个项目是否独立于任何公司或者组织的影响,其二是看贡献者在社区内活动是代表他们个人,还是作为公司或者组织的代表出现在社区并进行活动的。

Apache 基金会 Top Level 的项目即顶级项目,在毕业阶段都会从这些维度进行综合的判断。只有各方面都达标的项目,才会被允许从 Apache 基金会的孵化状态中毕业而成为成为 Top Level 的项目。这也是逼着个人比较喜欢 Apache 顶级项目的原因。

另外,OpenSSF 项目的 Criticality 评分(参见 https://github.com/ossf/criticality_score)也是一个不错的参考指标,它会度量一个项目的社区贡献者数量、提交频度、发版频度、被依赖的数量等指标,来判断一个开源软件在开源生态中的重要程度。这里就不详细展开了,有兴趣的同学可以参考它的资料,个人认为是一个值得参考的方向,但是这个评分还处于早期阶段,距离理想状态还比较远。

五、根据项目的质量指标来进行选择

很明显,有些开源软件的代码质量是比其他开源软件的质量好。 有的时候需要从项目的质量情况来选择开源软件。

这个时候,我们需要查看一些被业内广泛证明比较有效的指标。

其中 MTTU 是被知名开源供应链软件供应商 SonaType 所推荐的指标。 

MTTU(Mean Time to Update):即开源软件更新它依赖库的版本的平均时间。举个例子来说,某开源软件 A 依赖于开源库 B,假设 A 的当前版本是 1.0,依赖 B 的版本是 1.1。某天开源库 B 的版本从 1.1 升级到了 1.2,然后一段时间之后,开源软件 A 也发布了新版本 1.1,其中把对 B 的依赖版本从 1.1 升级到了 1.2。这个时间间隔,即从开源版本 B 的版本升级到 1.2 的时间点距离开源软件 A 的新版本 1.1 的发布时间,称之为 Time to Update

这个时间反映出来的是开源软件 A 的研发团队,根据依赖库的更新周期,同步更新它的依赖版本的能力。Mean Time to Update 是指这个软件的平均升级时间。数值越低表明质量越好,表明该软件的负责人在很快速升级各种依赖库的版本,在及时修复各种依赖库引起的安全漏洞问题。

据 SonaType 的统计,业内开源软件的更新升级时间 MTTU 越来越短。在 Maven 中心仓库上的 Java 类开源软件,2011 年平均的 MTTU371天2014年平均的MTTU为302天,2018 年平均的 MTTU 是 158 天,而 2021 年平均的 MTTU 时间是 28 天。能看出来,随着开源软件库更新频率的加快,使用它们的软件也加快了更新版本的速度,MTTU 相对 10 年前,时间缩短到原来的 10/1 以下。

当然 MTTU 只项目质量的一个间接纬度。 历史上是否爆出重要高危安全漏洞,修复响应是否快速及时等等也是开源项目质量评价的重要维度。

某些大厂的安全部门,会不断评估开源软件的安全情况,把某些屡屡发生高危安全漏洞,但是修复不及时的开源软件设定为不安全软件,列入到内部的开源软件黑名单中对内公示,并要求各个业务研发团队不再使用这些软件如果实在因为研发和人力问题不能迁移到新的软件系统也需要把这些老服务迁移到一个相对封闭的网络环境中,减少风险可能造成的损失。这个时候,显然应该需要遵守公司的安全规定,不再使用黑名单上的开源软件。

六、从开源软件所属于的开源社区治理模式角度来考虑

还有一个维度,即从开源项目的社区治理模式来考虑,适用于需要长期进行开发和维护的项目。

社区治理模式(Governance Model)主要是指该项目或者社区是如何做决定的以及由谁来做决定。 具体表现为: 是所有人都可以做贡献吗还是少数几个? 决定是通过投票的方式产生的,还是通过权威?计划和讨论是否可见?

常见的开源社区和开源项目的治理模式有如下三种:

单一公司主导:特点是软件的设计、开发和发布都由一个公司来控制,也不接受外部贡献。开发计划和版本计划不对外公开,相关讨论也不对外公开,版本发布时候才对外公开源码。例如 Google 的Android 系统。

独裁者主导(有个专有名词 “Benevolent Dictatorship”,翻译为 “仁慈的独裁者”):特点是由一个人来控制项目的发展,他有强大的影响力和领导力,一般都是该项目的创始人。例如 Linux Kernel 由 Linus Torvalds 来负责,Python 之前由 Guido Van Rossum 来主导。

董事会主导:特点是有一拨人构成项目的董事会来决定项目的重大事项。例如 Apache 软件基金会的项目由该项目的 PMC 决定,CNCF 的基金会的决策是 CNCF 董事会来负责(很多技术决定授权给了 CNCF 董事会下的技术监督委员会)。

个人意见和经验,根据该开源软件背后的开源社区的治理方式来进行选择优先级的排序如下:

优先选择 Apache 毕业项目因为这些项目的知识产权情况清晰,而且至少有三方在长期维护

次优选择 Linux 基金会等其他开源基金会的重点项目因为 Linux 基金会的运营能力很强,每个重点项目后面往往都有一个或者多个大公司在支持

小心选择一个公司主导的开源项目因为该企业的开源战略随时可能会调整,很有可能不再持续支持该项目,例如 Facebook 就是一个弃坑很多的公司

尽量不选择个人开源的项目个人开源更加随意,风险尤其高,但是不排除某些已经有很高知名度,并且跑出长期维护模式的项目,例如知名开源作者尤雨溪(Evan You)所负责的 Vue.js 开源软件。

这是个人推荐的选择同类开源软件项目的优先级顺序,仅仅代表个人观点,欢迎讨论。

 

本文已刊发于开源精选集《开源观止》第 2 期,更多精彩内容,请点击下载:

https://oscimg.oschina.net/public_shard/opensource-guanzhi-20220707.pdf

正文到此结束
本文目录