1 背景與解決思路
做灰度發(fā)布,主要有兩個(gè)大的方向
- 在代碼中做。一套線(xiàn)上環(huán)境部念,代碼中做開(kāi)關(guān),對(duì)于不同的用戶(hù)走不同的邏輯
- 在接入層做氨菇。多套(隔離的)線(xiàn)上環(huán)境儡炼,接入層針對(duì)不同用戶(hù)轉(zhuǎn)發(fā)到不同的環(huán)境中
來(lái)分別看下這兩種方案的優(yōu)缺點(diǎn)
方案 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|
在代碼中做 | 靈活,粒度細(xì)查蓉;一套代碼(環(huán)境)運(yùn)維成本低 | 灰度邏輯侵入代碼 |
在接入層做 | 無(wú)需(少)侵入代碼乌询;風(fēng)險(xiǎn)小 | 多套線(xiàn)上環(huán)境,運(yùn)維成本高 |
脫離具體的應(yīng)用場(chǎng)景談解決方案都是耍流氓豌研。具體到我們的業(yè)務(wù)場(chǎng)景:
- 對(duì)線(xiàn)上的質(zhì)量要求高妹田,目前無(wú)單測(cè),QA黑盒測(cè)試鹃共,無(wú)自動(dòng)化
- 變更周期長(zhǎng)(可接受)鬼佣,單次迭代功能點(diǎn)多
- 流量低峰期在22點(diǎn)后,整體回歸時(shí)間長(zhǎng)霜浴,且存在漏測(cè)情況
可以看到我們要做灰度發(fā)布的主要訴求是保證線(xiàn)上的質(zhì)量晶衷,盡量降低因迭代帶來(lái)的服務(wù)問(wèn)題。而非要針對(duì)于不同的用戶(hù)做AB Test坷随》棵考慮到如果灰度的方案涉及到修改代碼驻龟,則可能引入其他不確定的風(fēng)險(xiǎn)温眉,在此,我們采用第二種翁狐,也就是在接入層做分流的策略类溢。
2 具體實(shí)現(xiàn)方案
2.1 接入層 -> Web層
接入層采用nginx,可以基于IP或cookie的方式進(jìn)行分流露懒,由于我們是商業(yè)ERP系統(tǒng)闯冷,有用戶(hù)登錄的邏輯,自然選擇基于cookie的策略懈词。
就基于cookie的分流策略而言蛇耀,又有兩種實(shí)現(xiàn)方案
- nginx維護(hù)Cookie名單文件,每來(lái)一個(gè)請(qǐng)求看Cookie是否在名單中坎弯,做不同的轉(zhuǎn)發(fā)
- nginx不維護(hù)Cookie名單文件纺涤,根據(jù)Cookie的特征進(jìn)行轉(zhuǎn)發(fā)
第一種方案的缺點(diǎn)顯而易見(jiàn)译暂,每次請(qǐng)求判斷是否是灰度用戶(hù)時(shí)間復(fù)雜度為O(N);且變更名單撩炊,需要操作接入層服務(wù)外永。我們采用第二種方案,具體的實(shí)現(xiàn)策略
- 業(yè)務(wù)中維護(hù)白名單文件(存放在數(shù)據(jù)庫(kù)中)
- 在登陸時(shí)拧咳,如果用戶(hù)在名單中則給用set特定標(biāo)識(shí)的Cookie伯顶;退出或Session過(guò)期后Cookie失效
- nginx匹配特定Cookie,做轉(zhuǎn)發(fā)
這樣骆膝,調(diào)整灰度的范圍祭衩,只需要操作數(shù)據(jù)庫(kù)即可,無(wú)需重啟服務(wù)谭网。
2.2 Web層 -> 核心層模塊
目前兩層模塊之間的解耦方式是通過(guò)Zookeeper汪厨,對(duì)這部分的灰度發(fā)布的實(shí)現(xiàn),是通過(guò)caller, callee約定一個(gè)固定的節(jié)點(diǎn)名稱(chēng)(可以把具體的版本號(hào)寫(xiě)進(jìn)去)來(lái)實(shí)現(xiàn)愉择。
3 運(yùn)維上的升級(jí)
3.1 維護(hù)灰度的機(jī)器
我們采用${index}.${platform}.${module}來(lái)管理模塊和機(jī)器的對(duì)應(yīng)關(guān)系劫乱,多了一個(gè)灰度的機(jī)器,在${platform}中增加一個(gè)stage平臺(tái)名锥涕,代表實(shí)驗(yàn)環(huán)境衷戈。
實(shí)驗(yàn)環(huán)境也屬于線(xiàn)上環(huán)境,需要增加對(duì)應(yīng)的監(jiān)控层坠。
全流量的機(jī)器不包含實(shí)驗(yàn)環(huán)境的機(jī)器殖妇,獨(dú)立部署,轉(zhuǎn)全后全流量的流量也不會(huì)落到stage機(jī)器上(nginx的upstream.conf文件不用動(dòng))
3.2 建立灰度編譯打包破花、部署任務(wù)
全流量的編譯打包谦趣,和灰度的打出來(lái)的包,是一樣的座每,版本號(hào)也一樣前鹅。
只在灰度部署的任務(wù)中,自動(dòng)更新注冊(cè)節(jié)點(diǎn)名稱(chēng)峭梳。
由于要固定caller, callee的ZK節(jié)點(diǎn)名稱(chēng)舰绘,所以,強(qiáng)制在灰度部署任務(wù)中葱椭,增加一個(gè)stage的標(biāo)記邏輯捂寿。
3.3 nginx的轉(zhuǎn)發(fā)邏輯
增加對(duì)于帶cookie的請(qǐng)求轉(zhuǎn)發(fā)
location / {
# ...
if ($http_cookie ~* "SPECIALID.*|$") {
proxy_pass http://stage-cluster;
}
proxy_pass http://default-cluster;
}