1. 為什么要灰度發布
- 互聯網服務變動頻繁,發布周期短。速度與質量總是難以雙全。
- 灰度發布能降低發布風險,減少影響范圍。
- 降低對測試的依賴,減少線下自測的數據構造成本。
- 方便集中監控日志,全量發布由於各層負載均衡的作用,很難跟蹤一條完整的調用鏈路。
- 可以灰度測試帳號,測試賬戶通過之后再灰度真實用戶帳號,進一步降低發布的風險和影響。
- 方便回滾。
不能靠灰度發布解決的問題
需要強調的是:上文所說的“可以容忍的影響”必須是可恢復的,比如API無法調用一段時間,但是修復之后,就可以成功調用。而永久性地丟失或者破壞用戶數據(比如商品信息、訂單信息等),則是不能容忍的。因此,互聯網企業的架構師有責任通過設計完善的后備措施(比如用戶數據的定期備份、寫操作的業務流水日志等),在生產系統錯亂導致丟失用戶數據的情況下,仍能夠通過人工干預,根據歷史記錄(備份數據、流水日志等),把丟失的用戶數據修復至不久之前(比如一小時前至一周前)的狀態。
TIPS 先灰度測試帳號的灰度策略,可以降低破壞或者丟失真實用戶的數據的風險。
2. 期望達到什么效果
不管是那種變更,我們都希望特定的請求能夠路由到我們的變更版本(灰度版本),以便觀察和驗證。
3. 灰度策略
其實就是什么的請求應該路由到我們的灰度版本(灰度機器)上來。這個往往是業務強相關的。比如對於API來說,一般有如下幾個需求:
- 特定用戶(比如測試帳號)
- 特定的App(比如測試app或者合作App)
- 特定的模塊、接口(只有某些接口需要灰度,這種一般是API Container的修改,拿一些不是很重要的API做灰度測試。)
- 特定的機器(某些請求IP轉發到灰度機)
4. 灰度方案探討
方案一、代碼級別通過對約定好的flag判斷,動態的進行新老切換——Amazon的做法
實現:
在代碼中埋開關,做if-else判斷,對於需要灰度的機器,設置開關為on,否則為off。每次版本發布都是有兩個版本。
優點
- 快速回滾,不需要重新發布和重啟系統。
缺點
- 對代碼有傾入性。
- 分支邏輯,帶來復雜性。
這種方式筆者曾經應用過,就是在阿里的時候把商品的數據庫從Oracle切換到MySql,使用了一個狀態變量進行控制。從而打到平滑遷移的效果。
方案二、預發布機——Alibaba的做法
其實這個不是真正意義上的灰度。因為這個預先發布機器是內部IP,沒有對外服務的。需要綁定域名進行驗證。但是數據是完全的線上。所以本質上是灰度某些特定用戶(可以訪問灰度機器的用戶,內部測試用戶)的一種簡單做法。其實API這邊也有類似的做法,就是我們的Gamma環境,而且我們還提供了Gamma機器的域名,方便外部合作用戶配合測試。
優點
- 簡單
缺點
- 浪費一台機器(這個可以預先發布完成之后投入正式環境,預發布的時候從nginx摘除,不過需要運維支持。)
- 不夠靈活
- 只能針對接入層機器,IDL服務灰度需要另外考慮。
方案三、SET部署
1. 按照業務隔離部署
比如現在API Container的做法,部署的粒度可以到API級別,前端根據nginx進行轉發。比如:
- 微購物 API Container: api.weigou.qq.com
- 拍拍 API Container:api.paipai.com
- 易迅 API Container: api.yixun.com
- 網購 API Container:api.buy.qq.com
上面是大業務級別的隔離部署。還可以進一步細化到模塊級別,比如虛擬服務電商的API,是掛在拍拍下面的一個子業務模塊,但是由於他們接入微信之后,訪問量大增,為了避免影響拍拍其他業務,也為了避免受其他業務影響,API這里是給他們單獨部署了兩台機器,nginx配置一下就可以將針對虛擬的API訪問引流過來了:
虛擬API Container:http://api.paipai.com/v2/virbiz
這樣,我們在發布一個版本的時候,可以先選擇業務量最小的易迅進行發布,觀察沒有問題再全量其他平台。
2. 按照用戶隔離部署
這個對於開放平台來說不是很適合,不過對於SNS這種應用場景就很合適了。比如QQ系統,按照用戶號碼段分為若干個set,每個set包含連續1億個號碼的用戶。假設現在最新的QQ號碼接近10億,則總共有10個set(Set 1到Set 10)。這樣每次可以選擇其中一個SET進行發布,而且高位QQ往往是不是很重要的用戶,所以會先發布SET10。
優點
- 隔離部署,各個業務線影響最小。自動支持灰度發布。
缺點
- 灰度的粒度取決於隔離部署的粒度,一般會偏大。
- 相對於集中部署比較浪費機器。
- 各個業務線版本可能不一致,不利於統一管理。
- 有一定的實現和部署成本
方案四、動態路由
方法:采用一個可以靈活配置的灰度策略,影響Load Balance的行為,讓其根據灰度策略,返回灰度服務的IP和端口。
適合與后台IDL的服務灰度。
優點
- 靈活,可控。
缺點
- 現在的配置中心和L5本身沒有考慮指定路由策略,且不具有擴展性,需要在其外邊開發。
- API的元數據來源比較分散,目前 API和IDL元數據,API等級和頻率限制 分布在不同的數據源,現在需要增加一個 灰度路由 數據源。
灰度發布一般有三種方式 nginx+lua,nginx根據cookie分流,nginx 根據權重來分配:
nginx+lua根據來訪者ip地址區分,由於公司出口是一個ip地址,會出現訪問網站要么都是老版,要么都是新版,采用這種方式並不適合
nginx 根據權重來分配,實現很簡單,也可以嘗試
nginx根據cookie分流,灰度發布基於用戶才更合理