Web部署变得相当简单:S3,网克和遗留系统

作者:Joe Bernardi.

今年夏天的某个时候,我们开始考虑将OkCupid的桌面web应用程序转换成一个更有spa风格的体验。188bet金宝搏官网“为什么不呢?“我们问。“真奇怪,我们没有早点开始做这件事!”这可能是别人说的话。

也许一天后,我回答说:“哦。”

为了处理任何自重SPA所需的代码分割和延迟加载,我们需要在已编译的文件名中包含内容哈希值。

这是一个问题,因为(不祥,汉斯Zimmer的噪音,或者也许是一个响亮的唱片暂存)Okcupid的Web开发基础架构很大程度上依赖于检查编译的JavaScript和CSS进入版本控制。188bet金宝搏官网使用不同哈希的扁平文件泛洪存储库不是一个选项。

在大家对我发火之前,让我们先回顾一下

如何部署工作

直到最近,我们的工作流程看起来是这样的:

  1. 编写一些javascript或CSS。
  2. 将这些更改提交到我们的前端存储库。
  3. 运行webpack来编译它们,使用一个手工制作的插件将编译好的文件通过NFS发送到我们的开发服务器和主存储库。
  4. ssh进入dev服务器。
  5. 将编译的文件提交到主存储库。
  6. json文件中的手工编辑行来处理缓存,每个已编译文件的一个值。
  7. 将JSON文件提交到主存储库。
  8. 部署已编译的文件。
  9. 单独部署JSON文件,其中文件名的新值将作为一个新的查询字符串包含在页面上。

我花了大约一个月的时间来开发一个完整的部署过程的心理模型。如果有任何打破,快速回滚通常意味着使用git恢复到编译文件的过期版本,将我们的两个存储库留在一个强调我键入的状态。这是耗时,烦人的,容易出错,但它也在大部分时间工作,所以我相信你了解我们的困境。

我开始将项目套装为一些低悬垂的水果,并发现Webpack-Manifest-Plugin.通过为每个编译的文件生成唯一的内容哈希表,插件可以取代我们在一个大JSON文件中手工增加数字的部分,并可以通过忘记逗号或其他任何东西让应用程序在所有平台上消失。

测试插件一开始很顺利,但我很快意识到CSS文件被分配了与JS文件相同的内容哈希值。事实证明,Webpack 3的内容哈希(就像几乎所有其他常见的javascript基础设施一样)并不知道如何通过Webpack的Extract-Text-Plugin生成CSS文件。common.min.js.common.min.css.是一种相同的文件,插件,直到他们不是。

我们将需要一些东西来生成CSS文件的单独内容哈希。Extract-Text-Plugin包括一个要在文件名本身中包含它们的功能,但我们还没有准备好。

(深叹了)我们需要一种方法来从文件名中拉出内容哈希。幸运的是,WebPack Manifest-Plugin包含一个地图让我们在清单中弄乱任何条目的方法,但我们认为适合。例如,我们可以使用从其文件名派生的准确介绍CSS文件的JS相同的内容哈希。

(We’re aware Webpack 4 can do this much more sensibly, but the CommonsChunk/SplitChunks schism would have collided so directly with OkCupid’s usage of Webpack that upgrading fell out of scope pretty much immediately. If you don’t know what I’m talking about, I am very jealous of you.)

通过纠正的清单进入到位,我们可以自由地将哈希从CSS文件名中重新表达式。通过杂耍在向我们的Dev服务器发送编译的文件之前,我们可以在不手动编辑任何JSON的情况下部署。

不知怎么,它工作。我们在路上。

通过编程方式破坏缓存,我们的部署可以从端到端自动化。这意味着我们可以开始处理从版本控件中获取文件,这反过来允许我们在文件名中包含内容哈希,开始创建SPA,然后继续使用我们的生活。

每个人都有一个问题:如果平面文件不会在我们的服务器上托管,那么他们会被托管?一群美国耸了耸肩,同时说“S3”,之后很快就创造了一个桶。

依赖S3的一个优点是存在S3-Plugin-Webpack,它将Webpack编译的结果放入用户选择的S3存储桶中。向它的开发人员致敬——设置它是件轻而易举的事,除非我忘记了S3不是一个真正的文件系统,因此如果您试图使用相对路径上传到它,就会完全崩溃。

有了这个问题的答案,我们可以继续第二个问题:如果我们不打算在版本控制中跟踪我们的构建,在哪里我们要跟踪他们吗?不幸的是,这个问题需要两个以上的字符来回答:

现在部署是如何工作的

  1. 和以前一样:写、提交、编译。
  2. 将扁平文件和WebPack ManageSts发送到S3而不是我们的Dev服务器。
  3. 每个Webpack构建都有一个版本,这是一个由构建最近的git提交组成的字符串,它串联到时间戳。
    3 a。一排deploy_log.为此创建数据库表版本
    3B。每个版本对应于一个Webpack清单,它位于S3下面$ {revision} / $ {platform} / manifest.json
  4. 如果一个版本被标记为积极的在数据库中,OkCupid将指代对188bet金宝搏官网应的清单。

有了这个系统,以及一个基于web的仪表盘来管理我们的部署,我们就能够将我们的文件包含在经典的文件中common.49313671.min.css命名约定。

于是我们有了它:一个几乎是一对一的替代品,取代了曾经令人困惑的大麻烦。然而,“接近”引起了足够多的质疑,于是提出了一个实验:我们一半的用户将通过S3获得资产服务,另一半将通过老式的方式获得资产服务。在理想情况下,这两组用户之间的统计数据应该是相等的。

如果你已经读到这里,你可能已经知道这两个事实,但是:世界并不完美,额外的http请求会产生影响。从S3获取Webpack清单时引入了一个这样的请求,这使得平均加载时间增加了足够多的毫秒,使得我们的投票/滑动总次数增加了大约1.5%。不可持续的。

如果通过HTTP获取清单不会是一个选项,则下一个最简单的解决方案似乎存储了彼此的百分之一的JSON行版本在数据库中获取它。“为什么不呢?”我们问。“真奇怪,我们没有早点开始做这件事!”这可能是别人说的。

我部署了大约五分钟后,我收到了从Erwan,我们的系统架构师的桌子上的点击。在指向他的监视器之后,在各种图表中脱掉烟花时,他解释说,如果我在大约二十分钟内没有回滚任何我刚刚完成的东西,那么数据库将开始变得无响应。

我把它卷了回来。

事实证明,我们的部署日志的后端服务将在基础上实现高速缓存。我们使用的方法,调用get_active_deploy,返回版本但没有其他信息。为了获取部署的清单,a第二方法是必需的。在每个页面视图上。在每个平台上。

你明白我的意思了吧。在实验失败的挫败感中,我鲁莽地在不到10分钟的时间里将OkCupid数据库的呼叫量增加了30%。188bet金宝搏官网

当我明白了我的愚蠢之处后,我们的后台工程师Josh在最后一刻提供了不可思议的帮助,我们创建了一个新的方法,包括更全面的响应和所有我们需要的缓存。我们重新做了这个实验,这次成功了(也就是说什么都没发生)。从存储库中删除了平面文件,我们的部署过程中人为错误的可能性大大降低,一切都很好。

大多数Okcup188bet金宝搏官网id的技术债务是在我们的时间决定方面略微提出的结果,以便在之后很快就可以在更广泛采用的方式解决的问题。我们造成自己的床的程度意味着没有人这些基础设施问题,更不用说解决了。习惯一个复杂而笨拙的系统可能会让人很难想象在它之外的事情是如何工作的,因此决定将一些宝贵的开发时间投入到潜在的开发解决方案上并不是轻率做出的。然而,几个月后,项目成功了,我们的web团队的生活质量有了显著的提高。

在本月后不久,我需要完成我的构建过程的心理模型,我被分配了一个叫做的票“不要检查编译文件”。大约一年半后,我完成了它。(但是,在那段时间后,票子已经掌握了很好的埋葬,并且在大约五分钟后,我放弃了试图关闭它。)

如果没有别的,我希望这篇文章能激励一些人用一些遗留代码玩叠叠乐。如果这是一个糟糕的建议,请随时与我争论推特,甚至是更好的,来这里工作和我亲自上的小丑。

最初出版https://tech.188bet金宝搏官网okcupid.com.2019年1月30日。

188bet金宝搏官网Okcupid Tech Blog.

阅读OkCupid工程团队每天连接数百万人的188bet金宝搏官网故事

188bet金宝搏官网Okcupid Tech Blog.

188bet金宝搏官网Okcupid的工程团队负责每天匹配数百万人。阅读Okcupid Tech Blog上的故事188bet金宝搏官网

188bet金宝搏官网Okcupid Tech Blog.

188bet金宝搏官网Okcupid的工程团队负责每天匹配数百万人。阅读Okcupid Tech Blog上的故事188bet金宝搏官网