十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
前言

前段時(shí)間在面試的時(shí)候遇到過前端灰度發(fā)布相關(guān)的問題,剛好在之前公司有設(shè)計(jì)過前端灰度發(fā)布的方案,這套方案也在多個(gè)系統(tǒng)上得到過驗(yàn)證了,最近有時(shí)間整理,現(xiàn)在也拿出來和大家交流下,在結(jié)尾也給大家留下了一些的代碼實(shí)現(xiàn),有興趣的伙伴可以去查看下
tips
關(guān)于灰度規(guī)則的一些放量算法也比較容易找到,這篇文章重點(diǎn)不是講算法,只是更多貼合實(shí)際場(chǎng)景把灰度方案落地,對(duì)于放量算法有高要求的伙伴可以自行搜一下放量算法相關(guān),桶漏、令牌算法等
什么是灰度發(fā)布
將某個(gè)功能灰度發(fā)布(逐漸放量)給特定線上人群,避免新功能全量上線帶來的風(fēng)險(xiǎn)
上白話文,某項(xiàng)目當(dāng)前處于1.0版本,但是想更新一個(gè)1.1版本,1.1版本內(nèi)測(cè)沒有問題了,但是由于改動(dòng)了關(guān)鍵的功能,想要實(shí)現(xiàn)只給一部分線上用戶使用體驗(yàn),看看反饋。
這個(gè)時(shí)候線上就需要一部分用戶繼續(xù)用1.0版本,一部分用1.1的版本,如果1.1版本接收到反饋的問題嚴(yán)重到影響上線了,那么就回退1.0版本,影響的用戶范圍比較小,如果1.1版本穩(wěn)定,那就直接給所有用戶過度到1.1版本。實(shí)現(xiàn)這種場(chǎng)景效果,就是灰度發(fā)布。
什么是灰度規(guī)則?灰度規(guī)則可以是用戶等級(jí)、性別、地區(qū)、客戶端等業(yè)務(wù)信息或者設(shè)備信息,比如灰度規(guī)則設(shè)定為廣東地區(qū)的用戶放問1.1版本,那么廣東用戶訪問項(xiàng)目的時(shí)候就算命中了灰度規(guī)則,給他們轉(zhuǎn)去1.1版本,其他地區(qū)的用戶繼續(xù)使用1.0版本
常見灰度發(fā)布方案
灰度方案各式各樣,既有多樣就有對(duì)比,沒有最好,只有最合適自己的業(yè)務(wù)場(chǎng)景,這里給大家介紹幾種方案,以便大家做比較選擇
1. 簡(jiǎn)單ngxin分流(推薦指數(shù):??)
本身只依賴nginx來做的分流還算不上灰度發(fā)布的,但是偶然間跟朋友聊起了他們小公司的騷操作實(shí)現(xiàn),賴著說要我寫進(jìn)來,說他們已經(jīng)試驗(yàn)過了
優(yōu)點(diǎn): 簡(jiǎn)單,不涉及后端操作
缺點(diǎn):
2. nginx + lua + redis(推薦指數(shù):????)
tips:這套方案可能是沒找到好的資料或者對(duì)這套方案理解得不夠深刻,我們覺得靈活性有些欠缺,比較難結(jié)合復(fù)雜的業(yè)務(wù)做過多的灰度邏輯判斷,如果有大佬用過這套方案的,求不吝賜教。
nginx + lua + redis方案網(wǎng)上的資料也比較多,大家可以自行了解,雖然我們對(duì)著套方案理解不透徹,從整個(gè)鏈路長度理論來看這套方案效率應(yīng)該是比較高的,所以還是給大家貼了一些文章參考
參考文章1[1]
參考文章2[2]
參考文章3[3]
3. 服務(wù)端渲染分流(推薦指數(shù):??????)
服務(wù)器渲染分流的方案,其實(shí)也是我覺得比較好使的一個(gè)方案,這里我先做一些流程簡(jiǎn)述,后續(xù)也會(huì)單獨(dú)對(duì)著一塊做一些介紹
優(yōu)點(diǎn):靈活、可控性強(qiáng),可結(jié)合業(yè)務(wù)體系做灰度放量規(guī)則 缺點(diǎn):幾乎是后端一把梭,對(duì)服務(wù)器有壓力,需要多做相關(guān)優(yōu)化,多頁面應(yīng)用使用比較麻煩
4. 客戶端注釋判斷(比較難維護(hù))(推薦指數(shù):推條毛毛,不推薦)
客戶端通過注釋條件編譯,來做灰度,其實(shí)就是根據(jù)灰度規(guī)則對(duì)應(yīng)在代碼層面上做判斷顯示哪些版本的功能,這種方案也有公司在使用,灰度功能一但多了,極其難維護(hù),不推薦,這里就不過多介紹了
5. nginx + 服務(wù)端 + redis + [前端sdk] (推薦指數(shù):??????)
整體方案概述
sdk的使用場(chǎng)景:
項(xiàng)目中需要在特定的時(shí)機(jī)觸發(fā)灰度功能,點(diǎn)擊某個(gè)按鈕,或者進(jìn)入某個(gè)頁面,比如某些應(yīng)用是會(huì)彈出彈窗,告訴用戶 有內(nèi)測(cè)版本,是否需要體驗(yàn),點(diǎn)擊同意后才跳轉(zhuǎn)到灰度版本
方案設(shè)計(jì)圖示
名詞代號(hào)
具體實(shí)現(xiàn)(簡(jiǎn)單演示)
4. 后端服務(wù)邏輯:
后臺(tái)實(shí)現(xiàn)代碼
//這里只是演示,直接通過鏈接獲取用戶id,實(shí)際場(chǎng)景應(yīng)該是通過獲取用戶會(huì)話去判別用戶相關(guān)信息
const uuid = ctx.query.uuid;
//可以進(jìn)入灰度版本的uuid,在數(shù)據(jù)庫存放
const uuids = ['123','456','789']
//redis 中存放了的的用戶id,如果清理了redis,則意味著,取消用戶的版本標(biāo)識(shí),這里簡(jiǎn)單的用數(shù)組存放,實(shí)際應(yīng)用場(chǎng)景根據(jù)各自的業(yè)務(wù)信息考慮是否需要多集合存放
const redisUuids = [{id: '789', version: 'beta'}, {id: '333', version: 'stable'}];
上面代碼邏輯是當(dāng)uuid為123或者456或者789的時(shí)候就命中灰度規(guī)則,就進(jìn)入beta版本 redis中已經(jīng)存放了uuid為789和333的用戶了
5. 效果:
灰度問題處理操作
代碼
彩蛋代碼
公司后端是用了java去實(shí)現(xiàn)的,在這里為了方便大家更好的去理解整個(gè)流程,也用node給大家實(shí)現(xiàn)了一遍,有興趣的小伙伴去可以直接去看代碼github[4],大體的設(shè)計(jì)思路是一樣的
注意點(diǎn): 為了方便運(yùn)行查看演示,我們是通過docker compose來跑的,在有docker和docker compose的前提下,可以直接通過命令跑起示例
docker-compose build
docker-compose up -d
localhost:8000
結(jié)語
方案千千萬,選擇自己合適的就好,演示代碼中只是簡(jiǎn)單的寫了一些邏輯性的代碼,并不是真正可放到項(xiàng)目的邏輯,具體還是要結(jié)合實(shí)際的項(xiàng)目場(chǎng)景調(diào)整,前端sdk和java部分的代碼沒有放出來,是因?yàn)樵摲桨敢呀?jīng)在公司實(shí)行過的,不便放出,大家可以根據(jù)大致的思路來編寫,文中有錯(cuò)的地方或者有更好的方案還望各位大佬不吝賜教