一段时间在今年夏天,我们开始思考OkCupid的桌面Web应用程序转变成一种更具SPA式体验。188bet金宝搏官网“为什么不呢?”我们问道。“真奇怪,我们没有早点开始这么做!”这句话可能是别人说的。

也许过了一天,我回复说:“哦。”

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

urls-best

这是一个问题,因为OkCupid的web开发基础结构严重依赖于将编译好的javascript和CSS检查为版本控制。188bet金宝搏官网用不同散列的平面文件填充存储库是不可行的。

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

如何部署工作

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

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

我花了大约一个月,以发展我们的部署过程中的一个完整的心理模型。如果有什么突破,快速回滚经常使用Git恢复到了过期版本的编译的文件,留下我们两个储存在多数民众赞成强调我出去,我键入此状态的意思。这是耗时的,烦人,而且容易出错,但它也工作的大部分时间,所以我敢肯定你了解我们的困境。

我开始套管项目为一些低挂水果,发现Webpack-Manifest-Plugin。通过为每个编译文件独特的内容哈希值,该插件可以取代我们的过程,其中,重申,我们手递增的数字在一个大的JSON文件中的部分,并可以通过遗忘逗号或任何需要应用了所有的平台上。

插件测试一开始进行得很顺利,但我很快意识到CSS文件和JS文件被分配了相同的哈希值。结果是,Webpack 3的内容散列(就像几乎所有其他常见的javascript基础设施一样)并不真正知道如何通过Webpack的Extract-Text-Plugin生成CSS文件。Common.min.jsCommon.min.css是相同的文件,插件说,直到他们不是。

samehash-best

我们需要一些东西来生成CSS文件的独立内容散列。Extract-Text-Plugin包含了一个特性,可以将它们包含在文件名中,但是我们还没有准备好这样做。

(深深的叹息)我们需要一种方法从文件名中提取内容散列。幸运的是,Webpack-Manifest-Plugin包含地图方法,该方法允许我们以任何我们认为合适的方式打乱清单中的任何条目。例如,我们可以将CSS文件的与js相同的内容散列替换为来自其文件名的精确散列。

pull-hash-besst

(我们知道Webpack 4可以更明智地做到这一点,但是CommonsChunk/SplitChunks的分裂会直接与OkCupid对Webpack的使用发生冲突,以至于升级很快就超出了范围。188bet金宝搏官网如果你不知道我在说什么,我真的很嫉妒你。)

随着修正到位清单项,我们可以自由地正则表达式的散列出来的CSS文件名。通过编译后的文件发送给我们的开发服务器之前杂耍这一切,我们可以部署没有手动编辑任何JSON。

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

随着高速缓存目前正在编程打掉,我们展开时可从终端到终端的自动化。这意味着我们可以开始对获取的文件进行版本控制,这将反过来让我们包括文件名中的内容散列,开始创建SPA的工作,并与我们的生活继续前进。

每个人都有一个问题:如果平面文件不在我们的服务器上,在哪里他们会被招待吗?我们一群人耸耸肩,同时说“S3”,然后很快就创建了一个bucket。

依托S3的一个优点是存在S3-Plugin-Webpack,其卡紧的WebPack汇编成用户的选择的S3桶的结果。脱帽向它的开发者,设置它是一件轻而易举的,除了当我忘了S3是不是一个真正的文件系统,因此完全怪胎,如果您尝试使用相对路径上传到它。

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

部署现在如何工作

  1. 和以前一样:写、提交、编译。
  2. 在平面文件和舱单的WebPack发送到S3,而不是我们的开发服务器。
  3. 每个Webpack构建都有一个,这是由构建最近的Git提交串接一个时间戳的字符串。
    3 a。一排deploy_log为此创建数据库表
    3B。每对应于的WebPack清单,其居住在S3下${修订}/ ${平台}/ manifest.json
  4. 如果一个被标记为活性在数据库中,OkCupid将把其对188bet金宝搏官网应的清单。

随着该系统到位,管理我们部署了一个基于Web的仪表板,我们能够为包括经典的我们的文件common.49313671.min.css命名约定。

仪表板。

还有我们曾经拥有过:一个将近一换一替换什么曾经是一个很大的混乱令人失望。在“近”,然而,筹集了足够的眉毛实验提出:半我们的用户将获得通过S3服务的资产,一半会得到他们的老式的方法。在一个完美的世界里,用户的这些群体之间的统计信息将是相等的。

如果您已经远远看了这个,你可能知道这两个事实了,但:世界上没有完美的和额外的http请求有所作为。撷取的WebPack清单从S3引入一个这样的请求,该请求由约1.5%足以毫秒增加的平均加载时间到罐我们整体票/挥动的数量。不可持续的。

如果通过http取货单是不会是一个选项,接下来最简单的办法似乎是存储百或那么旁边的JSON的线并以这种方式获取它。“为什么不呢?”我们问道。“真奇怪,我们没有早点开始这么做!”这句话可能是别人说的。

大约五分钟后,我部署了变化,我收到了从二万,我们的系统架构师我的办公桌上水龙头。在他的显示器,其中各种图表是像烟花起飞后指出,他解释说,如果我没ROLL什么我大约二十分钟之内刚刚做回来,该数据库将开始变得反应迟钝。

我把它卷了回去。

结果,我们部署日志的后端服务实现了基于每个方法的缓存。我们使用的方法叫做get_active_deploy,返回但没有额外的信息。为了获取该部署的清单,一第二个方法是必需的。在每一个页面视图。在每一个平台。

你看到我这个打算。在我的无奈在实验中不工作,我会从臀部开枪在不到十分钟增加OkCupid的数据库调用了大约30%的体积。188bet金宝搏官网

在我理解了我的愚蠢之处之后,再加上我们的后端工程师Josh在最后一刻提供的一些不可思议的帮助,我们创建了一个新方法,其中包括更全面的响应和所有我们可以要求的缓存。我们返回实验,这次成功了(读:没有发生什么)。从存储库中删除了平面文件,我们的部署过程发生人为错误的可能性大大降低,一切正常。

无平文件

许多OkCupi188bet金宝搏官网d的技术债务是已经稍稍领先我们的时代,决策的结果,以手工卷的解决方案被做,将在更广泛采用的方式不久之后需要解决的问题。在何种程度上,我们就做我们自己的床意味着从来没有人这些基础设施的问题,更解决了他们。习惯一个拜占庭和尴尬的系统可以让人很难想象的事情怎么可能在外面工作的它,并决定奉献一些宝贵的开发时间缩短到只有潜在的R&D'荷兰国际集团的解决方案并没有轻易做出。几个月后,尽管该项目已经成功了,我们的网络团队的生活质量有显著改善。

在我完成构建过程的心智模型一个月后不久,我被分配了一个名为“不要检入编译文件”的票据。大约一年半后,我完成了它。(不过,在这段时间里,这张票已经被埋得很好了,大约五分钟后,我就放弃了关它的努力。)


如果没有别的,我希望这篇文章能激励一些人用一些遗留代码来玩叠叠叠叠。如果这被证明是一个糟糕的建议,请随意与我争辩推特或者,甚至更好 -来这里工作和小丑在我身上。