前端灰度發(fā)布落地方案
大廠技術(shù) 高級(jí)前端 Node進(jìn)階
點(diǎn)擊上方 程序員成長指北,關(guān)注公眾號(hào)
回復(fù)1,加入高級(jí)Node交流群
一個(gè)大型的前端項(xiàng)目在發(fā)布時(shí),都會(huì)采取灰度策略。第一次聽同事說灰度的時(shí)候,還是停留在疑惑階段,對這個(gè)詞不了解,后續(xù)做了一些功課,才明白灰度的意義。
很多時(shí)候,不可能全量放出一個(gè)新的feature,可能帶來的風(fēng)險(xiǎn)很大,一般都會(huì)先進(jìn)行部門灰度,然后再20%,40%灰度,直到全量發(fā)布。
那到底灰度是啥,它的原理是什么,可以參考超神熊貓寫的文章,說不定對你所幫助,本文值得收藏后閱讀~
作者:超神熊貓
鏈接:https://juejin.cn/post/7010751591087079460
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
前言
前段時(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í)際場景把灰度方案落地,對于放量算法有高要求的伙伴可以自行搜一下放量算法相關(guān),桶漏、令牌算法等
什么是灰度發(fā)布
將某個(gè)功能灰度發(fā)布(逐漸放量)給特定線上人群,避免新功能全量上線帶來的風(fēng)險(xiǎn)
上白話文,某項(xiàng)目當(dāng)前處于1.0版本,但是想更新一個(gè)1.1版本,1.1版本內(nèi)測沒有問題了,但是由于改動(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)這種場景效果,就是灰度發(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ā)布方案
灰度方案各式各樣,既有多樣就有對比,沒有最好,只有最合適自己的業(yè)務(wù)場景,這里給大家介紹幾種方案,以便大家做比較選擇
1. 簡單ngxin分流(推薦指數(shù):??)
本身只依賴nginx來做的分流還算不上灰度發(fā)布的,但是偶然間跟朋友聊起了他們小公司的騷操作實(shí)現(xiàn),賴著說要我寫進(jìn)來,說他們已經(jīng)試驗(yàn)過了
-
兩份代碼,分別部署 -
通過nginx加權(quán)輪詢來控制訪問百分比(在客戶端cookie不存在標(biāo)識(shí)的前提) -
前端引入了sdk(熊貓瞄了下源碼,其實(shí)就是往cookie存入一個(gè)隨機(jī)不重復(fù)(還只是大概率不重復(fù)吧)的標(biāo)識(shí) -
二次訪問的時(shí)候,nginx通過對cookie中的唯一標(biāo)識(shí)來返回對應(yīng)的版本
優(yōu)點(diǎn): 簡單,不涉及后端操作缺點(diǎn):
-
只能簡單依賴nginx加權(quán)輪詢百分比來控制流量,全靠前端,無法結(jié)合業(yè)務(wù)做分流 -
可控性弱,在灰度版本出現(xiàn)問題的時(shí)候,只能通過修改nginx配置來讓用戶回退版本 -
問題收集能力差,只能等待用戶反饋 -
在客戶端cookie被清理掉后,用戶需要重新通過nginx的加權(quán)輪詢進(jìn)入,有可能被分配到與上一個(gè)分配不同的版本
2. nginx + lua + redis(推薦指數(shù):????)
tips:這套方案可能是熊貓沒找到好的資料或者對這套方案理解得不夠深刻,熊貓覺得靈活性有些欠缺,比較難結(jié)合復(fù)雜的業(yè)務(wù)做過多的灰度邏輯判斷,如果有大佬用過這套方案的,求不吝賜教。
-
當(dāng)用戶請求到達(dá)前段代理服務(wù)nginx,內(nèi)嵌的lua模塊解析nginx配置文件中的lua腳本代碼 -
lua變量獲取到客戶端的ip地址,去查詢r(jià)edis緩存內(nèi)是否有該建值,如果有返回值執(zhí)行灰度版本邏輯,否則執(zhí)行當(dāng)前生產(chǎn)環(huán)境版本
nginx + lua + redis方案網(wǎng)上的資料也比較多,大家可以自行了解,雖然熊貓對著套方案理解不透徹,從整個(gè)鏈路長度理論來看這套方案效率應(yīng)該是比較高的,所以還是給大家貼了一些文章參考參考文章1參考文章2參考文章3
3. 服務(wù)端渲染分流(推薦指數(shù):??????)
服務(wù)器渲染分流的方案,其實(shí)也是我覺得比較好使的一個(gè)方案,這里我先做一些流程簡述,后續(xù)也會(huì)單獨(dú)對著一塊做一些介紹
-
前端打包好的兩份代碼分別部署到服務(wù)器上(這里以單頁面應(yīng)用為例,多頁面的話需要單獨(dú)處理一些其他細(xì)節(jié)) -
在后臺(tái)管理添加版本(實(shí)際上就是讓服務(wù)端讀取單頁面的index.html) -
客戶端訪問服務(wù)端,服務(wù)端根據(jù)灰度規(guī)則set-cookie并在redis存儲(chǔ),返回對應(yīng)版本的index.html -
二次訪問通過服務(wù)端的時(shí)候,如果存在cookie并且redis已經(jīng)存在對應(yīng)的版本信息,則直接返回,否則重新走灰度流程
優(yōu)點(diǎn):靈活、可控性強(qiáng),可結(jié)合業(yè)務(wù)體系做灰度放量規(guī)則 缺點(diǎn):幾乎是后端一把梭,對服務(wù)器有壓力,需要多做相關(guān)優(yōu)化,多頁面應(yīng)用使用比較麻煩
4. 客戶端注釋判斷(比較難維護(hù))(推薦指數(shù):推條毛毛,不推薦)
客戶端通過注釋條件編譯,來做灰度,其實(shí)就是根據(jù)灰度規(guī)則對應(yīng)在代碼層面上做判斷顯示哪些版本的功能,這種方案也有公司在使用,灰度功能一但多了,極其難維護(hù),不推薦,這里就不過多介紹了
5. nginx + 服務(wù)端 + redis + [前端sdk] (推薦指數(shù):??????)
整體方案概述
-
我們先把線上的穩(wěn)定版本稱為stable版,本次發(fā)布的新功能版本稱為beta版 -
開發(fā)人員給stable和beta版本各自啟動(dòng)了nginx服務(wù),在運(yùn)維層啟動(dòng)了一層入口nginx服務(wù),作為轉(zhuǎn)發(fā)
-
客戶端通過域名訪問項(xiàng)目,通過請求灰度規(guī)則,命中灰度規(guī)則后,并給客戶端設(shè)置cookie作為標(biāo)識(shí),并將用戶標(biāo)識(shí)存放到redis,將用戶重定向到指定的版本 -
灰度規(guī)則接口請求的時(shí)候,如果已經(jīng)帶有cookie則直接返回對應(yīng)版本,不存在cookie則去查找redis,redis中存在對應(yīng)信息則直接返回,如果不存在則走灰度規(guī)則識(shí)別流程 -
前端sdk功能:用于控制發(fā)起灰度規(guī)則請求的時(shí)機(jī)、回調(diào)操作和其他業(yè)務(wù)操作 sdk的使用場景:\color{#1d7dfa}{sdk的使用場景:}sdk的使用場景:項(xiàng)目中需要在特定的時(shí)機(jī)觸發(fā)灰度功能,點(diǎn)擊某個(gè)按鈕,或者進(jìn)入某個(gè)頁面,比如某些應(yīng)用是會(huì)彈出彈窗,告訴用戶有內(nèi)測版本,是否需要體驗(yàn),點(diǎn)擊同意后才跳轉(zhuǎn)到灰度版本
方案設(shè)計(jì)圖示
名詞代號(hào)
-
stable:正式生產(chǎn)環(huán)境(1.0版本) -
beta:灰度版本(1.1版本) -
uuid:代碼演示中,沒有做賬號(hào)系統(tǒng),沒有登錄行為,所以通過url上帶上uuid作為用戶id來走流程 -
具體實(shí)現(xiàn)(簡單演示)
-
分別創(chuàng)建兩個(gè)html假設(shè)是兩個(gè)項(xiàng)目,beta是新功能灰度版本,stable是當(dāng)前生產(chǎn)環(huán)境版本 -
在前端引入sdk(前端sdk非必須,看業(yè)務(wù)場景使用) -
前端發(fā)起請求,獲取版本信息(如果引入了sdk,可以通過配置做這一步驟)
4. 后端服務(wù)邏輯:
后臺(tái)實(shí)現(xiàn)代碼
//這里只是演示,直接通過鏈接獲取用戶id,實(shí)際場景應(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í),這里簡單的用數(shù)組存放,實(shí)際應(yīng)用場景根據(jù)各自的業(yè)務(wù)信息考慮是否需要多集合存放
const redisUuids = [{id: '789', version: 'beta'}, {id: '333', version: 'stable'}];
復(fù)制代碼
上面代碼邏輯是當(dāng)uuid為123或者456或者789的時(shí)候就命中灰度規(guī)則,就進(jìn)入beta版本 redis中已經(jīng)存放了uuid為789和333的用戶了
-
效果:
灰度問題處理操作
-
問:如果在上線后灰度版本出現(xiàn)嚴(yán)重的問題,需要緊急回退操作 答:直接后臺(tái)關(guān)閉灰度功能,清除redis,結(jié)束用戶的登錄會(huì)話(實(shí)際是清除客戶端cookie操作) -
問:需要指定某個(gè)用戶進(jìn)入某個(gè)版本 答:后臺(tái)修改redis信息,結(jié)束用戶的登錄會(huì)話 -
問:指定項(xiàng)目中某個(gè)頁面才啟用灰度 答:可以在前端sdk中處理相關(guān)邏輯,把相關(guān)的頁面路徑作為名單給前端識(shí)別(sdk最好動(dòng)態(tài)引入,sdk放在cdn上)
代碼
彩蛋代碼\color{red}{彩蛋代碼}彩蛋代碼 公司后端是用了java去實(shí)現(xiàn)的,熊貓?jiān)谶@里為了方便大家更好的去理解整個(gè)流程,也用node給大家實(shí)現(xiàn)了一遍,有興趣的小伙伴去可以直接去看代碼github,大體的設(shè)計(jì)思路是一樣的
注意點(diǎn): 為了方便運(yùn)行查看演示,熊貓是通過docker compose來跑的,在有docker和docker compose的前提下,可以直接通過命令跑起示例
docker-compose build
docker-compose up -d
localhost:8000
復(fù)制代碼
近況
最近是處于一個(gè)離職的交接期,在離職期間,熊貓?jiān)谀壳暗墓臼且粋€(gè)前端組的小頭目,在提出離職一周后,優(yōu)先開始做了管理崗相關(guān)的交接,在做完管理方面的交接后呢,迅速就被OOXX了,哈哈哈哈,面對一些人的態(tài)度也開始轉(zhuǎn)變,心里拔涼拔涼的,原本排了計(jì)劃給團(tuán)隊(duì)做一些基建的優(yōu)化和幾個(gè)課題的分享,也許并不需要熊貓?zhí)傩牧耍P(guān)掉了之前的博客站,轉(zhuǎn)到了在掘金這邊學(xué)習(xí)也試著更新一些文章,有一些心態(tài)上的調(diào)節(jié),也更多的心思回歸到技術(shù)的同時(shí)也好好整理一下自己,接下來做好離職前的技術(shù)項(xiàng)目交接就散場了,感謝給過熊貓點(diǎn)贊支持的靚仔靚女們。
結(jié)語
方案千千萬,選擇自己合適的就好,演示代碼中熊貓只是簡單的寫了一些邏輯性的代碼,并不是真正可放到項(xiàng)目的邏輯,具體還是要結(jié)合實(shí)際的項(xiàng)目場景調(diào)整,前端sdk和java部分的代碼熊貓沒有放出來,是因?yàn)樵摲桨敢呀?jīng)在公司實(shí)行過的,不便放出,大家可以根據(jù)大致的思路來編寫,有疑問歡迎來跟熊貓討論,文中有錯(cuò)的地方或者有更好的方案還望各位大佬不吝賜教。
我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。

“分享、點(diǎn)贊、在看” 支持一波??
