10月17, 2016

【译】Twitter如何部署其JavaScript插件

原文:http://www.zcfy.cc/article/1359

部署是一件艰难又容易让人沮丧的事。许多Bug都会在这期间暴露出来,尤其是在代码变动很大的情况下。那么如果要向上百万人同时部署呢?接下来我将讲述我们团队如何在这种规模上安全轻松的进行部署工作。 Web开发者使用一个单独的JavaScript文件, widgets.js,来在网页中嵌入Twitter的内容。嵌入推文、时间轴、Tweet按钮都使用同一个JavaScript文件,很大程度上方便了Web开发者在自己的网站上集成插件。我们每周都会进行更新,修改bug以及添加新特性。使用者什么都不需要做就可以获取更新。

不过为了保证用户可以简单操作,我们往往要做一些复杂的工作才行。况且,我们想要部署的是一个独立的,未版本化的,知名的,稳定的资源,并且要开发者信任其在自己网页中运行。每个月十亿的访问量使得这段代码大致每秒运行300,000次。这对我们来说是一种责任和使命,因此最近我们开始致力于升级widgets.js的部署过程,来发现一些早期错误,以免给用户留下不良印象。

一种安全的部署

我们按照理想中部署的标准开始进行这个项目。具体来说,我们制定了之后在安全部署上要达到的三个要素:

  • 可逆性: ‘Rollback first, debug later’是我们的座右铭。回滚应当是快速,便捷,简单的。理想中,它应当是一个能使我们放下心来的巨大红色开关。

  • 增量 :所有的代码都是有Bug的,而部署总能以一种不可思议的方式暴露这些bug。因此我们希望可以分阶段的发行新代码。

  • 可视化:我们需要图表来同时展示两个版本的widgets.js的情况,并且要有深层研究国家,浏览器类型,以及插件类型的能力。这些图表都需要实时展示让我们知道部署怎么样了以便于必要时采取行动。

这些是我们给自己设定的目标。好了,现在我们继续探讨如何完成它们的细节。

如何部署工作

由于 widgets.js 比较出名(platform.twitter.com/widgets.js),在文件名上没有加上版本控制,因此控制其部署过程十分艰难。我们最终控制这个新版本文件发行的方式是由我们的域名,platform.twitter.com,在DNS层面解决的。这种方式使我们可以通过建立规则在部署期间决定使用新版本文件或是旧版本文件。 __

部署结构图

为了能在我们的DNS上实施控制,我们不得不配置了三个组件:

DNS管理服务:这是个让我们控制platform.twitter.com如何处理一个IP地址的服务。我们按照地理区域来控制转出,基于如下三条规则来对应部署的相应阶段: 阶段1: A地区5%的流量请求IP2,其余的请求IP1。 阶段2: A地区100%的流量请求IP2,其余请求IP1.并且不断的增大区域。 阶段3: 所有流量都请求IP2。包括TOR流量和任何无法识别地区来源的请求。

CDN(内容分发网络):这个一个为我们的静态资源提供高性能分发方式的服务。我们配置了当一个请求经过了IP1,将由ORIGIN 1来提供资源,否则由ORIGIN 2提供资源。

Origin:一个用于widgets.js上传的存储服务,就像Amazon S3。CDN会向Origin申请最新的版本提供出来。

默认的状态是所有的请求都由ORIGIN 1响应。在部署的开始会向ORIGIN 2中上传 widgets.js的新版本。然后我们开始像上面描述的那样通过阶段1到阶段3来把流量转移至ORIGIN 2。一旦部署成功了,我们就将ORIGIN 2中的资源拷贝到ORIGIN 1中,然后将流量重置回ORIGIN 1。

评价新的部署过程

我们的目标是执行安全的部署,所以我们来评价一下我们都做了什么。通过使用两个Origin,我们可以立即进行回滚 — 这里的回滚就是把所有的流量转移至保存着旧版本widgets.js的ORIGIN 1中。基于地理位置的部署让我们可以逐步的部署新版本,并且只要当前是安全的就可以继续进行下去。再有就是我们的客户端代码记录了发行版本,让我们可以建立实时的图表看到部署是否成功。

一次成功的部署就像今天这样:

一次成功部署中流量在新旧版本之间的转变

我们使用这种部署方式近一年了,并且和之前相比更快的检测到几个回退。例如最近我们代码中有一个bug,是关于一个延时加载的JavaScript文件的地址不正确而导致了我们的插件渲染不完全。多亏了这个部署过程,我们很快的看到了问题并且在它对用户产生广泛影响之前处理了它。

下一步

对于下一次迭代我们有很大的构想。其中之一就是我们认识到我们的DNS规则还可以更优化。还有就是在阶段1使用少量关键用户来让我们快速的意识到去进行危机回退。而阶段2中,我们想用更多的典型用户来捕获一些只有在一定规模下才会出现的微妙的bug。为了匹配这几个阶段的目标,未来需要对一些DNS规则进行调整。

另一方面我们想要提高的就是总的部署时间。由于过多的片段转移,我们的部署时间已经从几分钟增加到了几小时,这是因为我们从一个阶段到另一个阶段每次移动流量时都要等待中间缓存失效。

之后我们也将加入性能指标,以便于我们可以扩展我们的发行审核从单纯的成功/失败到更深层的表现上,例如不同地区的渲染时间等等。

我使用了外部供应商CDN和DNS管理,并且我上面提到的DNS层面的配置都使用了 开源API,所以你部署的时候也可以使用。总的来说,我们很开心使用如今新的部署过程进行工作,它促使我们更多的更新以保证使用者操作便捷。

英文原文:https://blog.twitter.com/2016/how-twitter-deploys-its-widgets-javascript

本文链接:http://crystalmiao.com/post/how-twitter-deploys-its-widgets-javascript.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。