2008年秋季,Netflix遭遇了一次严重的数据库故障,连续3天无法向成员寄送DVD,从那时起,他们决定向云迁移。今年2月,Netflix宣布完成了向云的迁移。
而与之相应的是,Netflix的开发工作也要针对上云做很多工作。那么,Netflix的代码在部署到云上之前,是如何构建的呢?
Netflix的三位工程师Ed Bukoski、Brian Moyles和Mike McGarr撰文介绍了相关的工具与技术。
Netflix之前已经开源了其持续交付平台Spinnaker。Spinnaker可以快速可靠地将软件变更发布到多种云平台。
从上图可以看到,很多工作是依托Spinnaker平台进行的。
一行代码在进入Spinnaker之前,还要经过很多步骤:
- 在本地使用Nebula构建和测试
- 修改被提交到一个中心git仓库
- 使用Jenkins作业执行Nebula,构建、测试和打包应用,准备部署
- 将构建“baked”到Amazon Machine Images中
- 使用Spinnaker流水线部署和提交代码变更
关键词:文化、云和微服务
Netflix是一家非常强调“文化”的公司。其中有一点是“Freedom & Responsibility(自由与责任)”。该文化激励和促使工程师使用自己感觉最适合的工具来完成任务。如果一个工具广为接受,它肯定是很有竞争力,能够带来巨大的价值,并减少大部分工程师的整体认知负荷。团队可以自由地实现替代方案,但也有责任维护这些方案。
另外两个关键词也不难理解,前面我们提到,2008年开始,Netflix开始向云上迁移,一体化的、基于数据中心的Java应用转向基于云的Java微服务。
下面就具体看一下代码部署步骤。
构建
Nebula是Netflix开发的Gradle插件集合,可以让开发者更方便地使用Gradle构建、测试和部署项目。也已经开源。
Gradle为构建、测试和打包Java应用提供了很好的支持。之所以选择它,是因为方便编写可测试的插件,还能减小项目构建文件的大小。Nebula通过一些插件在依赖管理、发布管理和打包等方面扩展了Gradle。Nebula提供了可复用和一致的构建功能,同时减少了每个应用构建文件中的样板代码。
集成
代码在本地经过Nebula构建和测试之后,已经为持续集成和交付做好了准备。第一步是将更新后的源代码推送到某个git仓库。变更提交会触发一个Jenkins作业。
最早,在Netflix的数据中心中,只有一个大规模的Jenkins主节点,而现在,他们在AWS中运行着25个主节点。Jenkins被用于很多自动化任务,不单是简单的持续集成。Jenkins作业会调用Nebula来构建、测试和打包应用代码。根据所构建内容的不同,Nebula还会构建出.jar文件、Debian或RPM包,并根据配置发布到相应位置。
Bake
Netflix的部署策略是围绕Immutable Server (不可变服务器)模式进行的。为避免配置漂移 (configuration drift) 并确保部署可以从源代码重复进行,线上修改应该尽量避免。所以每次部署都会创建一个新的Amazon Machine Image(AMI)。
为从源代码生成AMI,Netflix创建了Bakery。Bakery提供了一个API,支持全局创建AMI。Bakery API服务会在工作节点上调度真正的bake作业,使用Aminator来创建Image。
在Jenkins作业成功完成时,通常会触发Spinnaker流水线。Spinnaker会读取Nebula生成的操作系统包,并调用Bakery API来触发bake。
部署
一旦bake完成,Spinnaker就可以将生成的AMI用于部署了。
未来探索
Netflix希望进一步改进开发者的体验,做得更好。目前还面对一些挑战。
一个是积极解决二进制文件的依赖。Nebula提供了简化Java依赖管理的工具,不过还有很大的改进空间。
另一个是bake时间。
随着Netflix的不断增长,很多非JVM语言应用也越来越多,像JavaScript/Node.js、Python、Ruby和Go等,最好能有一套语言无关的方案和工具。
更多细节,可以阅读Netflix的相关技术博客。