写点什么

真正的持续集成:分布式代码仓库和依赖

  • 2017-05-08
  • 本文字数:2204 字

    阅读完需:约 7 分钟

微服务架构为软件开发带来了极大的灵活性,并加快了交付速度,但同时也带来了依赖管理问题。传统的解决方案虽然能够解决依赖管理问题,但都太极端,顾此失彼。于是,Netflix 尝试着寻找自己的解决方案,期待着在整个组织层面做到真正的持续集成。本文内容来自 Netflix 技术博客,已获得翻译授权,查看英文原文 Towards true continuous integration:distributed repositories and dependencies

在过去的 8 年间,Netflix 基于 AWS 构建了一套健壮的微服务架构,我们因此学会了如何在 AWS 上构建可靠的高性能服务。我们的微服务架构解耦了工程团队,让他们可以自由地构建、测试和部署他们的服务。这种灵活性最大化了团队的交付速度。在 Netflix,交付速度和可靠性是设计解决方案时首要的考虑点。

基于我们的架构,微服务为它们的消费者提供了一个客户端软件包,用于处理所有的 IPC(进程间通信)逻辑。这同时为服务的提供者和消费者带来了很多好处。除了客户端,微服务的很大部分是基于我们的运行时平台而构建的,这个平台由内部的软件包和第三方开源的软件包组成。

尽管服务开发团队有很大的发布灵活性,但他们的交付速度却受到了依赖软件包的影响。一项新增的产品特性可能要求很多微服务都用上最新版本的共享软件包或客户端,而更新依赖版本可能会带来风险。

简而言之,依赖管理是一项艰巨的任务。

更新项目的依赖可能带来潜在的问题。

  • 具有阻断性的 API 变更。这是最典型的场景,一个编译错误导致整个构建失败。由依赖锁定( Dependency Locking )和动态版本选择器组成的语义版本控制( Semantic Versioning )可以帮助大部分团队避免发生这种错误。不过,锁定在一个主版本上会让整个公司的代码升级变得很困难,导致配置漂移(Configuration Drift),并且需要长期地维护旧软件包。
  • 具有传递性的依赖更新。因为 JVM 的类路径是扁平结构,所以在一个应用程序里,一个类只能存在一个版本。像 Gradle Maven 这类工具可以处理版本冲突,避免同一个软件包的多个版本被引入到项目当中。这也意味着,你的应用程序里有一些代码依赖了具有传递性特征的软件包,但你的代码并没有针对它们进行过测试。
  • 具有阻断性的功能变更。理想情况下,这个问题可以通过执行适当的测试来缓解。软件包的所有者可以通过运行使用者的测试案例来了解他们对软件包功能的预期。

我们发现,为了解决大规模的依赖管理问题,很多公司使用了两种方案:共享最小化(Share Little)和单体仓库( MonoRepo )。

  • 共享最小化(或者干脆不使用共享软件包)最近在微服务领域很流行,它的核心论调是说,微服务之间不应该共享代码,服务之间只能通过 HTTP API 进行耦合。更有甚者,有人说直接使用拷贝加黏贴的方式来代替共享软件包。这是一种非常极端的解耦手段。
  • 单体仓库的核心论调是说,组织的所有代码应该全部保存在一个单独的仓库里。任何一个代码变更在提交到 HEAD 之前,都需要针对整个代码仓库进行编译和测试。内部软件包没有所谓的版本,只有 HEAD 代码。所有的提交在到达 HEAD 之前需要跨过一些门槛。第三方软件包需要通过“审批”才能被使用,而且仅限于一两个版本。

这两种方式都能解决大规模的依赖管理问题,不过它们也带来了一些挑战。共享最小化促进了解耦,也加快了工程速度,但牺牲了代码的重用性和一致性。单体仓库保证了代码一致性,并降低了风险,但牺牲了灵活性。不管采用哪一种方式,我们都需要对 Netflix 的开发基础设施和运行时架构做出重大的调整。况且,这两种方案会破坏我们所推崇的自由和责任文化

我们给自己提出了一个很大的挑战目标:

我们能否为 Netflix 的工程师们提供一种解决方案,它不但具有单体仓库的优势,还能保持分布式仓库的灵活性?

我们以单体仓库为蓝本,另辟蹊径,希望找出能够达到相同目的的可替代方案。单体仓库所要解决的核心问题是什么?我们能否在传统的二元集成世界里开发出一种新的方案?

我们的解决方案,虽然还在试验阶段,不过可以从中归纳出三个关键的特性。

  • 向发布者反馈。直接或间接地向共享代码所有者快速地反馈使用者所遇到的问题。同时,允许团队因下游依赖的中断而暂停发布。目前,我们不会把这类问题的责任归咎到使用者身上。通过向软件包所有者反馈他们的问题给 Netflix 带来的影响,希望他们能够负起应有的责任。
  • 来源管理。当有新版本发布时,为使用者提供一种安全的方式,用于自动增加软件包的版本。既然我们已经针对所有的下游依赖测试过每一个软件包,那为什么不直接让使用者知道新版本,从而加快新版本的采用速度呢!
  • 分布式重构。为共享代码的所有者提供一种方式,让他们可以全局地对 API 的使用者进行快速的重构。我们已经开始向使用了某些特定 Java API 的 Git 代码仓库发起了全面的拉取请求。我们已经做了一些试验,并希望在这方面有更多的投入。

我们的旅程才刚刚开始。我们的发布者反馈服务目前正处于 alpha 测试阶段,我们计划后续会大规模采用这个服务,紧接着会进行来源管理。我们的分布式重构试验让我们了解到进行快速的全局重构是多么的重要。我们也看到了通过我们所构建的工具来降低依赖图复杂度的可能性。我们相信,通过扩展和培养这种能力,我们的 Netflix 团队将会在组织层面做到真正的持续集成,并减少(甚至免去)依赖管理的痛苦。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-05-08 19:002530

评论

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

如何用内网渗透突破安全策略

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

来自北京大学NOIP金牌选手yxc的常用代码模板3——搜索与图论

Java 程序员 后端

新人问一般都用哪些 Linux 命令,我把这个扔了过去,linux基础及应用教程课后答案

Java 程序员 后端

无论你是什么职业,这篇职场生存法则都是你必备的,java微服务架构技术

Java 程序员 后端

普通程序员就不能有拥有架构师光环?想要建立架构思维,这份京东架构技术精髓一定不能错过

Java 程序员 后端

提升开发效率N倍的20+命令行神器,赶紧收藏了,mybatis原理图

Java 程序员 后端

数论 - 约数基础 【 试除法求所有约数 + 约数个数和约数之和

Java 程序员 后端

本科毕业斩获字节offer的我做了什么准备?大厂面试经验试题分享

Java 程序员 后端

是什么Java面试题PDF被Git全面封杀?刷完这套题已经拿完9个Offer!

Java 程序员 后端

普通本科,毕业六年,复盘一个月,mybatis一级缓存和二级缓存面试题

Java 程序员 后端

数据库中间件MyCat实战笔记(第一步),arm架构linux系统

Java 程序员 后端

数据库索引的原理,springcloud视频百度云

Java 程序员 后端

数据结构的栈和队列(这不进来看一看),计算机java语言入门

Java 程序员 后端

是什么让普通的链表也能达到二分查找的效率,你知道吗?

Java 程序员 后端

最新基准测试:Kafka、Pulsar-和-RabbitMQ-哪个最快,阿里Java笔试题目

Java 程序员 后端

拼多多3面+余额宝4面+蚂蚁金服5面,Java自学宝典

Java 程序员 后端

推荐这款牛掰的 API 敏捷开发工具,java程序设计教程课后题答案

Java 程序员 后端

斯坦福高效睡眠法-读书笔记,这可能是目前最全的

Java 程序员 后端

排除MySQL中常见错误的实用招术,什么是微服务扩展性和高可用、可扩展性

Java 程序员 后端

推荐一款技术人必备的接口测试神器:Apifox,不愧是大佬

Java 程序员 后端

月薪60k的Java开发在阿里是什么级别?对技术能力有哪些要求?

Java 程序员 后端

服了!阿里资深架构师发布SpringCloud笔记,在GitHub标星已达81

Java 程序员 后端

数据库ACID四大特性到底为了啥,一文带你看通透,java支付宝支付接口教程

Java 程序员 后端

数据结构系列第六部分:排序,Github爆火的《高并发秒杀顶级教程》

Java 程序员 后端

有个厉害的程序员老婆是什么体验?,mysql性能优化面试题

Java 程序员 后端

数据源的概念是什么?Springcloud+Mybatis如何使用多数据源

Java 程序员 后端

最近被安排搞搜索接口优化,压测了4次,才勉强达到要求

Java 程序员 后端

本科毕业斩获字节offer的我做了什么准备?大厂面试经验试题分享(1)

Java 程序员 后端

拜读!程序员60K+高薪技术,spring整合mybatis原理

Java 程序员 后端

拿捏了!ConcurrentHashMap!,宝塔linux建站教程

Java 程序员 后端

最新版SpringBoot开发实战:阿里技术官从基础到项目综合实战pdf

Java 程序员 后端

真正的持续集成:分布式代码仓库和依赖_DevOps & 平台工程_Netflix_InfoQ精选文章