2019 年 6 月 14 日
关注 @igormakaCocoaPods 1.7.2 为 主干规范存储库 带来了 CDN 支持的最终版本。
这是一个关于荒谬的规模、意外后果和免费开源计划的故事。CocoaPods 正在迁移到使用位于 https://cdn.cocoapods.org/ 的 CDN,并且仍被认为是实验性的。未来的版本将使其成为默认规范源。
CDN 是内容分发网络 - 这对 CocoaPods 来说意味着使用 CocoaPods 无需在计算机上保留所有公共 Podspec 的本地副本。为你节省了大约 1 GB 的文件存储空间,并且大幅缩短了 pod install
的时间。
免费和开源时的扩展
CocoaPods 是一个免费的开源项目,由维护者在业余时间运行。因此,它依赖于多家科技公司的恩惠和赞助。最初的决定是将规范存储在 GitHub 存储库中,这是免费开源项目存储此类元数据的常见做法。
第一个规模障碍是在 2016 年遇到的,当时主规范存储库的流量导致 GitHub 对所有操作进行速率限制。
当时 GitHub 的评论指出,仅此存储库就使用了 5 个完整的服务器 CPU,并消耗了数 TB 的带宽。
通过 分片存储库以提高算法性能并限制所有首次克隆为浅克隆,避免了这场危机。
这解决了 GitHub 的问题,但 CocoaPods 的用户仍然必须应对不令人满意的性能。
Git 作为数据库
Git 是在“网络速度慢”和“没有备份”被视为合理设计问题的时候发明的。作为持续集成的一部分运行无休止的构建并不常见。CDN 也没有那么普遍。
有很多关于 git 存储库达到 git 设计约束的硬边界的案例。Microsoft 的 Windows 存储库 就是一个例子。CocoaPods 是另一个。
在撰写本文时,规范存储库有
- 近 40 万次提交 - 几乎是 Linux 内核存储库的一半!
- 超过 40 万个目录
- 超过 30 万个规范文件
这些数字导致存储库克隆需要数分钟,更新需要很长时间,并且浪费了无数的 CI 时间。事实证明,它也抗拒 tarball,因为这种目录结构也会在 tar
中遇到瓶颈。
目录列表被拒绝
许多人显然认为应该将规范存储库放在 CDN 之后,但有几个限制
- 它必须是一个免费的 CDN,因为该项目是免费且开源的。
- 它必须允许某种获取目录列表的方法,用于检索 Pod 的版本。
- 它必须从 GitHub 自动更新,作为真实来源。
第一个实现是一个 shell 脚本,轮询 GitHub 并将 find
导入 ls
中,再导入索引文件中。这在不是开放或免费的机器上运行,因此不可能是真正的解决方案。尽管如此,这个自动更新的存储库还是放在了 jsDelivr CDN 之后,与之交互的客户端在 1.7.0 中发布,标记为“高度实验性”。
与 Netlify 的最后一圈
CocoaPods/Specs 的 CDN 的 最终版本是在 Netlify 上实现的,这是一个静态网站托管服务,支持灵活的网站生成。这个解决方案满足了所有要求:一个慷慨的开源计划、快速的 CDN 和来自 GitHub 的持续部署。
每次提交时,Netlify 都会运行一个 专门的脚本,该脚本会为存储库中的所有 Pod 和版本生成一个分片索引。如果你曾经注意到我们的 Podspecs 存储库的目录结构很奇怪,这就是我们所说的分片。分片索引的示例可以在 https://cdn.cocoapods.org/all_pods_versions_2_2_2.txt 中找到。这将对应于本地的 ~/.cocoapods/repos/master/Specs/2/2/2/
。
此外,我们还会创建一个 all_pods.txt
文件,其中包含所有 Pod 的列表。
最后,发出的任何其他请求都会重定向到 GitHub 的 CDN。
用法
虽然“已完成”,但使用 CDN 检索规范仍应被视为实验性的,直到我们将其切换为默认值。
要在 Podfile
中使用 CDN 源
如果你没有私有规范
source 'https://cdn.cocoapods.org/'
如果你有私有规范
source 'https://github.com/artsy/Specs.git'
- source 'https://github.com/CocoaPods/Specs.git'
+ source 'https://cdn.cocoapods.org/'
这样做会破坏你的 Podfile.lock
,所以你可能需要运行 pod update
来查看更改(小心,这可能会更新你的 Pod)。
如果你有 CI 设置,建议缓存新的存储库目录,因为它非常小,可以节省更多时间。在 1.7.2 中,它应该位于 ~/.cocoapods/repos/cocoapods-
(是的,带 -
),但我们希望在即将发布的版本中改进命名。
在即将发布的版本中,我们计划将 CDN 源设为默认源!
P.S. 感谢 @dnkoutso 为所有发布工作!
🚀