概述
灰度發布是最近一年在國內互聯網討論較多的一個話題。灰度發布在國外并沒有明確的定義,在國內的百科上如此定義
灰度發布是指在黑與白之間,能夠平滑過渡的一種發布方式。AB test就是一種灰度發布方式,讓一部用戶繼續用A,一部分用戶開始用B,如果用戶對B沒有什么反對意見,那么逐步擴大范圍,把所有用戶都遷移到B上面 來。灰度發布可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。
由此也可見灰度發布很多時候都和AB測試混在一起,但實際上灰度發布還包含了多級發布的概念。
11年,Facebook的David Wei寫了一篇文章《代碼和產品發布的幾種方式》明確分析了下幾個概念:
1、多級發布:也可以稱為分步代碼發布,是一種代碼發布的方式。基本操作是整個團隊共用一個代碼庫,一定頻率(比如每天一次,或者每周一次)把整個代碼的最新版本做一個新的發布分支(release branch),把發布分支逐步發布到產品線。
2、AB測試:這是一種很成熟的概念,是產品發布的常用手段。比起分步代碼發布,AB測試往往有更長的周期(比如幾個星期甚至幾個月)。基本操作是產品的開發者加一個或者多個配置控制(一般每個產品配置應該帶有配置的ID),允許通過調節相應的配置來讓一個產品發布到“逐步選擇”的用戶群。
從概念中可以看出多級發布和AB測試中最重要的區別:面向對象不一樣。多級發布針對的是代碼發布,AB測試針對的產品發布。本文主要討論代碼多級發布相關的需求和實現方案。
需求場景
在具體的互聯網應用中(主要針對如下架構)

多級發布的需求場景如下:
第一種:單個業務模塊上線,屬于具體一個業務中的一個模塊,非基礎模塊。有如下的特點:
- 50%的上線需求是這種場景。
- 上線流程:單機器-》多機器-》全部機器 的過程。
- 上線時間間隔非常短,一般在半個小時內完成全部上線。
- 會對用戶帶來影響,比如說用戶不停刷新有可能看到不同的版本。
第二種:基礎庫模塊上線。大部分的基礎庫上線會和第一種業務模塊上線類似,但部分上線(尤其是哪些影響業務模塊較多,修改較大,有高性能要求)也會有如下特點:
- 整體預估20%的上線需求,其中5%有如下特殊需求。
- 可能的特殊需求:分業務系統逐步上線到所有機器。
- 上線時間間隔有可能持續較長時間,比如說幾周以上。
- 基礎庫上線一般不會對用戶帶來影響。
第三種:多業務多模塊上線。一般這種上線的項目都是非常重要或者有重大功能修改的項目,重要性非常高。特點如下:
- 30%的比例。
- 一般上線流程是分業務上線。并且大體原則是從后(端)到前(端)。跨系統依賴的會梳理出順序,按照次序先后上線。
- 原則上各個模塊之間上線間隔都在小時或者分鐘級別。
- 對于具體用戶可見的部分會采用,有可能會用到長時間間隔的上線方式。
難點&解決方案
多級發布的主要難題有以下幾個:
- 監控完善到位。在每一級別的發布中,如何能夠快速的通過監控系統發現問題,包含功能異常、性能異常。
- 策略靈活可控。比如說能夠支持指定用戶查看某一級別的發布版本、能夠靈活的支持動態調度和動態擴容的需求。
- 用戶體驗無損傷。在發布的過程中,最好能夠保證用戶不會出現刷新版本頻繁切換的問題。PS:該問題在facebook也存在,但據說目前不care。
- 發布過程可測試。在發布的過程中,每一個階段都是可以方便確認功能正確性的。
同時多級發布也有一些限制,比如說同一個模塊的最多只能有一個上線流程在進行,也就是不支持同一個模塊多個版本并行上線。
其中監控需求,本身是一個相對獨立的需求,不在多級發布中考慮,那么多級發布只需要解決2、3、4三個難題。
多級發布解決方案按照不同的實現層度如下:
第一、實現多級發布基本功能:按照比例實現多級發布。
假設總共有16臺機器,分成8級發布,則可以按照1/8的分級方式進行上線發布。比如發布了第一級別后如下圖:

為什么要按照比例,而不是直接給機器劃分級別呢?主要是處于幾個考慮:
- 給機器不同的標簽定義會導致機器的異構化帶來維護的難度。
- 無法支持機器動態調度的需求。
- 無法支持機器數目擴容的需求。
第二、保證用戶體驗:采用一致性哈希負載均衡。
如何保證用戶體驗不受到影響的關鍵是:在多級發布的時候保證一個用戶的請求固定的落在一個發布級別中。那么對應的方法就是:前端接入層和運行層之間采用一致性哈希負載均衡算法。
這種算法有幾個依賴:
- 接入層和運行層的各個節點是無狀態對等的。原則上都會滿足。
- 在代碼發布階段,最好不能有機器的變更。如果有機器變更則會導致部分用戶在某一時刻出現業務版本的切換(原則上影響也不大)
對于一些默認不是一致性hash算法的,也可以在代碼發布的時候,把前端接入層和運行層之間的負載均衡方法切換到一致性哈希。
第三、可測性和靈活性:接入層引入規則通用庫。(如果接入層采用Nginx做反向代理,那么就是一個nginx擴展)
可測性是指:業務模塊的階段性發布能夠理解可測。這種需要只需要接入層規則通用庫能夠支持通過Http請求某一個參數來進行強制的請求分流即可。比如說通過參與version來指定對應請求分流的版本,具體比如說URL中有參數version=1,則分流到多級發布中的第一級。
靈活性:主要是指其他一些測試性的需求,比如說強制某些用戶分流在多級發布的某一級,這些同樣可以可以在接入層中實現。
本文首發
xlq的博客(轉載請保留)
http://blog.xiuwz.com/2012/03/05/%e6%b5%85%e8%b0%88%e7%81%b0%e5%ba%a6%e5%8f%91%e5%b8%83%e4%b9%8b%e5%a4%9a%e7%ba%a7%e5%8f%91%e5%b8%83/