最近有几个朋友提起”灰度发布"这个概念和相关的问题。想解释一下几种具体的发布方式(具体名称中文翻译不一定正确)、他们的优缺点和实现难点。

这几种方式都可以作为快速运营的软件或者web服务公司逐步发布新代码或者新产品,边尝试边改进的方法,这些方法可以避免一次发布里面某个产品/代码的漏洞对网站产生瞬间毁灭性的后果。 

几种方式各有优缺点和难点,根据实际情况一个公司可能使用不同的方法做不同的发布。

 

 

  • 分步代码发布(multi-phase code push):这是敏捷开发的团队常用的代码发布方式。基本操作是整个团队共用一个代码库,一定频率(比如每天一次,或者每周一次)把整个代码的最新版本做一个新的发布分支(release branch)把发布分支逐步发布到产品线。
  • 特点:"逐步选择"的过程不由代码控制(如果代码控制,那新一版本的控制代码有问题就可能让整个代码发布过程崩溃)。“逐步选择”过程由运营团队负责:比如选择每个机柜的第一台机器,或者每个机群的第一个机柜,或者多个数据中心里面选择某一个数据中心⋯⋯关键是选择的时候是均匀分布到各种不同的机器上。如果新代码在某一种配置的机器上有问题,运营团队能够及时发现。另外multi-phase code push的发布周期必须短于敏捷开发的迭代周期,往往一天或者一周之内要把代码发布到所有机器。
  • 监控:multi-phase code push一般要做实时的监控:代码逻辑错误的信息按照代码版本(比如svn revision number)来分类,保证新版本的代码不带来新的错误;硬件的信息(CPU内存IO)按照选择的机器、机柜、机群、数据中心分类:保证新的版本不引起更大资源消耗。当以上的信息都确认之后,可以给更大规模的机器安装新代码。
  • 难点:
  • 如果前端负载均衡器不能保证用户和机器一致的话,一个用户可能在发布过程中看到若干次新版本和若干次旧版本(比如第一个页面是新版本,而AJAX是旧版本),版本不兼容会造成Javascript错误、CSS错位,甚至一些逻辑错误;Javascript体系架构需要做一些安全检测,或者要求程序员开发的时候考虑版本兼容(一般在快节奏的web开发里面不容易);或者用保持用户和机器一致的前端负载均衡器;
  • 监控的时候硬件资源消耗信息有可能因为发布过程本身产生很大的扰动,而与代码无关(比如重启之后缓存要重新warmup,增大IO,产生虚报),这需要代码发布经理(pusher)的经验来排除。
  • AB测试(AB testing):这是产品发布的常用手段。比起分步代码发布,AB测试往往有更长的周期(比如几个星期甚至几个月)。基本操作是产品的开发者加一个或者多个配置控制(一般每个产品配置应该带有配置的ID),允许通过调节相应的配置来让一个产品发布到“逐步选择”的用户群。
  • 特点:“逐步选择”是一个有代码控制的逻辑过程。一般的产品基于用户ID选择;也有基于IP或者其他信息的。
  • 监控:AB测试的数据一般按照产品配置ID和打开/关闭状态分类,分析某个产品配置在打开的时候和关闭的时候对用户行为的影响,和对硬件资源的消耗,由此可以预测这个产品在100%发布之后的影响。
  • 难点:
    • 如何做选择:不同的产品有不同的选择方式。一般可以考虑用户ID,但如果跟浏览器的缓存效率关系很大的,可能需要考虑IP(因为一个浏览器可能被多个用户使用);如果对非注册用户做的产品(比如各种注册流程的测试),也可能需要IP,或者实时随机选取;
    • 产品效果的评价:有些产品需要有网络效应,如果按照用户ID随机抽取样本,网络效应可能被打破而使产品在AB测试期间失效 (比如一个社交网站的平均用户连接度是50,即一个用户连接其他50个用户,按照1%用户ID随机抽样的AB测试,那被选中的用户子群内部的连接度可能不到1)
    • "逐步选择"的逻辑本身是一个代码,如果这个代码写错的话可能带来灾难性后果。
  • 灰度上线(dark launch):我想“灰度上线”这个术语可能来源于dark launch。这是产品发布的另一种手段,往往用于需要一次发布的产品。 有一些产品可能因为市场营销策略的原因,或者因为产品本身的特点(比如Facebook的用户名注册,或者可能像火车售票系统)不能进行AB测试那样的逐步上线。同时,我们又需要知道这个产品一次上线的时候带来的影响,在这种情况下我们可以用灰度上线。基本操作是在用户访问网站的时候,打开新功能所需要运行的代码,但把用户可见的输出、互动和写操作都屏蔽掉,按照AB测试的方法逐步把这个去掉用户互动的产品发布出去。
  • 特点:外界感觉不到新产品的测试过程
  • 监控:和AB测试一样,但主要关注的是系统的负载和资源消耗
  • 难点:
    • 如何屏蔽用户互动:一方面要获得几乎真实的产品负载,另一方面希望不要把代码搞乱导致真正发布的时候需要很大改动;
    • 对真实产品发布后负载的预测:产品发布之后可能形成正反馈(比如一个产品发布之后大受欢迎,引起更多的用户注册⋯⋯)灰度上线只能预测第一层效果,不能预测用户行为的改变所引起的连锁反应。
这几种方式好像都被称作灰度上线,它们还是有很大不同的。根据产品发布需要,各有优劣。