管理依赖的终极秘密


prtyaa
prtyaa 2023-12-25 13:44:08 63458
分类专栏: 资讯

起先,我只是想写一篇如何提升软件质量的文章。后来在写质量文章的过程中,发现我还差一部分重要的内容没讲:依赖管理。于是,我着手准备写这篇文章,结果发现我还缺少一篇关于:依赖安全机制的文章——依赖孪生。所以,也就有了上一篇文章《依赖孪生:低成本的依赖安全方案》。
笑,为了安装好软件质量这个包,我已经陷入了依赖地狱了。
回到这篇文章,我们将介绍一些依赖管理的相关实践:从基础的依赖环境隔离到告别单体应用。


1. 依赖的环境隔离


事实上,针对于不同项目、不同语言进行环境隔离,本不是这篇文章讨论的范围。但是,我们又不得不提及一些相关的内容。因为,我们总是习惯性也忘记了相关的内容。
由于不同的编程语言的包管理工具,存在对于依赖的 link 机制,所以对于它们的管理也稍有不同:

  • 全局统一依赖型语言的环境隔离。对于诸如 Python、Ruby 这一类脚本型语言来说,它们使用的是全局依赖,所以需要依赖于诸如 virtualenv 或者是 rbenv 为每个项目创造一个独立的运行时依赖环境。
  • 项目独立的依赖隔离。对于使用 NPM 或者 Yarn 的前端开发人员来说,依赖存在于项目目录下的 node_modules,自然而然地就进行了依赖隔离,但是需要对 Node.js 的版本进行限定。稍微一提,这种机制特别浪费硬盘。
  • 包管理工具版本隔离。对于 Java 的 Gradle 来说,它稍有不同:统一的依赖存储路径,但是却不需要进行环境隔离,不过需要限定 Gradle 的版本。
  • 其它。由于我的语言经验有限,暂时只有这些案例。

:由于经验有限,上述内容有些可能不太准确,如有有错误,欢迎指正。
总之,我们需要针对于不同类型的语言和包管理工具,采用与之匹配的有效的依赖环境隔离。


2. 自建依赖创建

我们已经讨论了太多这方面的内容,这里就不详细展开了。

  • 对于中大型组织来说,可以自建自己的依赖中心。
  • 对于小型组织和团队来说,使用 Git 仓库也是一个不错的折中方案。

3. 进行 LICENSE 扫描


对于依赖的 LICENSE 进行管理和风险识别,是依赖管理的一个重要的部分。除了常见的商用管理方案之外,我们还可以采用诸如于 Node.js 项目中的 github.com/mwilliamson/ 或者是 github.com/3rd-Eden/lic 都是一些不错的工具。
至于 LICENSE 选择的问题,永远都是 MIT 优先。


4. 是否进依赖进行内联?


这是自 left-pad 事件之后,我采取的包的新策略(在我的开源项目上):对于小的软件包,直接复制源码,在项目中创建 third-party 放置相关的代码及 LICENSE。
这主要是结合了三个要素而考虑的:

  • 安全性
  • 可迁移性
  • 便利性(因人而异)

当然了内联依赖,涉及到一个版权问题——适合于代码少,不维护的项目。

5. 依赖的协议隔离策略


除了内联之外,我们还要考虑的一个问题就是依赖的协议问题。


策略1:再发布


当我们从 Google 上搜索代码的时候,往往会遇到代码在 gist、 stackoverflow 或者 codepen 上,它们非常适合于我们复制到项目中使用,但是难免地可能会遇到一些版权问题。对于开源项目来说,可以直接在项目中使用,并进行标即可。而对于外部项目而言,一种最简单的方式就是二次发布这些软件包。


又或者是对于一些已经不维护的依赖包,而我们又需要,那么就只能在修改后二次发布这些软件包。


策略2:二次协议 / 协议隔离层


对于 JavaScript / TypeScript 类库来说,在这方面的问题比较少,毕竟前端运行在客户端上,所以 Web 前端即『开源』。


如果真的非要使用某个开源软件,并且基于它之上修改,那么可以采取和 Android 开源协议类似的二次协议的方式。Linux 内核采用的是 GPL 协议,而 GPL 具有传染性——如果直接在 GPL 协议的类库上封装,那么只需要开源这部分的代码,因为认为我们的代码并不是衍生产品。而事实上 Free Software Foundation 动态地链接文件也产生了衍生产品,也就是说你用了 GPL 的库,你也需要开源你的代码。


为此,Android 系统在类库上采用的主要是 Apache-2.0 软件许可授权,对 GPL 进行了二次,它允许 Android 上的开发商基于 Android 的源代码进行开发而不向社区反馈。


所以,对协议进行隔离也是一个潜在可行方案,它从某种意义上将风险转移到了这一层级。


6. 依赖更新机制


在日常的业务开发中,最痛苦的一件事莫过于:没有时间做技术升级,没有时间处理技术债。在这个时候,对于依赖更新这个问题,可能就会变得非常痛苦:你可能要亲眼目睹一个遗留系统的形成。所以,作为一个有责任的开发人员,你应该尽量去说服相关的人员,去做好相关的技术更新和升级。


除此,当依赖发现更新的时候,是否有相应的工具可以提供我们?一些现代化的工具,诸如于 Intellij IDEA 可以帮助我们更新依赖。也可以尝试包管理工具自带的升级命令,诸如于 NPM 中的: npm outdated or npm outdated --parseable|wc -l。不过大多数时候,我们可能会放弃升级——除非我们不得不升级。除此,david-dm.org 也是一个不错的工具——用于开源的公开 Node.js 项目。


相似的工具还有 next-update 是一个不错的更新工具。又或者是同一个作者写的 next-updater 的工具。


7. 版本选择?宽松型,还是严格型


在引入依赖的时候,我们需要稍微注意一个对于依赖的版本选择问题:到是宽松型,还是严格型。依赖的版本问题,主要会出现在持续集成和新成员加入项目。诸如于使用兼容发布条款,如 ~= 0.6.4,对于那些早期已经搭建了的开发来说,并不会有问题。而新的成员安装的时候,可能就变成了 0.6.5,在 API 上可能会发现一些细微的变化 。而诸如于使用 * 匹配版本的话,就更不严谨。
以 Python 语言中的 requirements.txt 为例,存在不同的描述版本的方式:

  1. ~=: 兼容发布条款,如 ~= 0.6.4 等价于 0.6.*
  2. ==: 版本匹配条款
  3. !=: 版本排除条款
  4. <=, >=: 广泛的有序比较条款
  5. <, >: 排除的有序比较条款
  6. ===: 独断的比较条款


一些常见的情况如下:

  • 对于间断型维护的项目来说,往往选择严格型的依赖版本策略,因为大家都不想去碰了,哈哈。
  • 对于长期开发的项目来说,选择宽松型的依赖版本策略,可以让项目可容易维护。
  • ……

8. 使用依赖锁定


为了方便于在不同的开发人员之间能平稳地运行起项目,我们需要使用依赖锁定,以避免出现 DLL 地狱的问题。
DLL 地狱(DLL Hell)指 Microsoft Windows 系统中,因为动态链接库(DLL)的版本或兼容性的问题而造成软件无法正常执行。
为此,我们需要依赖锁定配置文件,来记录已经安装的依赖的确切版本。除此,它还描述了生成的依赖树及其关系,以便于可重现安装依赖(即在后续的安装中能够生成相同的依赖树),而忽略依赖的更新。
依赖锁定配置与依赖配置的最大区别在于,依赖配置文件只描述了需要哪些依赖及期版本,而依赖锁定配置描述了依赖的子子孙孙依赖及期关系。
如我们的一部分依赖是在内部服务器,那么在安装的时候只会从内部服务器拉取相应的依赖,不会去外部环境下载。这个时候,我们所能做的是拷贝依赖,或者是删除这个文件,重新生成。与此同时,这个依赖锁定文件可以通过源码控制工具(如 git)来进行管理。
常见的锁定配置文件有,Ruby 中的 Gemfile.lock,Node.js 中的 package-lock.json 或者 yarn.lock。无论你如何修改 package.json 的内容,它都会按照 package-lock.json 来安装依赖。


9. 依赖代码安全检查


就目前来说,常见的有两种方式:

笑~

10. 告别大的单体架构


我的意思并不是说微服务好——不过真的很香,我的主要目的是想说:大的单体应用在依赖上存在着滞后的问题。
对于微服务来说,频繁更新的服务,必然可以做出依赖的及时更新;而对于基本不修改的服务来说,我们基本不会考虑去更新依赖。对于某一长期开发的单体应用而言,它们采用新的构架和编程语言非常困难。因为某个接口的修改,导致要修改一系列的代码,有可能相当于重写整个应用。
诸如于 Spring 框架本身一直在更新,而你正在使用的版本是 2.x,那么你可能与新版本已经不兼容。甚至于,需要维护自己版本的 Spring——出于更新漏洞的原因,你们重写了系统中的部分软件。


11. == 什么是好的依赖

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=30307
赞同 0
评论 0 条
prtyaaL1
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1487
银河麒麟打印带有图像的文档时出错  1405
银河麒麟添加打印机时,出现“server-error-internal-error”  1194
统信操作系统各版本介绍  1116
统信桌面专业版【如何查询系统安装时间】  1114
统信桌面专业版【全盘安装UOS系统】介绍  1068
麒麟系统也能完整体验微信啦!  1026
统信【启动盘制作工具】使用介绍  672
统信桌面专业版【一个U盘做多个系统启动盘】的方法  616
信刻全自动档案蓝光光盘检测一体机  526
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!