<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一種前端灰度發(fā)布方案

          共 2140字,需瀏覽 5分鐘

           ·

          2020-01-07 23:25


          (給前端大學加星標,提升前端技能.

          作者:呂大豹?

          https://www.cnblogs.com/lvdabao/p/11920919.html

          本文介紹一種前端灰度發(fā)布方案,主要解決的是傳統(tǒng)的灰度發(fā)布只能以機器維度進行分組的問題。提供一種用戶維度分組的灰度發(fā)布機制。


          傳統(tǒng)灰度發(fā)布,因為是以機器分組,所以要求服務是無狀態(tài)的。所謂無狀態(tài)就是對請求的處理是上下文無關的。有長連接、讀寫文件、緩存等場景,就是所謂”有狀態(tài)“的。有狀態(tài)的服務,如果用戶的前一個請求打在機器A,后一個請求打在機器B,就會出問題。


          所以,有狀態(tài)的服務灰度發(fā)布,要做到:


          1. 同一用戶始終訪問同一版本的代碼

          2. 放量過程像傳統(tǒng)發(fā)布一樣可控


          本灰度發(fā)布方案對構建、部署、啟動服務、處理請求階段分別做改造,實現(xiàn)有狀態(tài)服務灰度發(fā)布。

          方案概述

          我們把線上的代碼稱為stable版,本次發(fā)布的新代碼稱為beta版。先整體描述一下方案:


          • 用git tag標識每次發(fā)布

          • 在構建階段生成tag,同時用tag名稱來命名manifest.json

          • 每次構建完新版本后,從cdn源機器取回上次發(fā)布的manifest.json文件,一并放在dist目錄下

          • 部署階段全量部署到所有機器,在運行階段來決定訪問哪個版本的代碼

          • node層啟動服務時,讀dist目錄下的兩份manifest.json文件,這樣就能拿到新舊兩個版本的文件清單

          • 處理請求時,根據(jù)動態(tài)配置的放量信息和分流策略,來決定使用哪個manifest.json中的文件

          • 版本號信息放在cookie中,以保證同一用戶始終訪問同一版本代碼

          開發(fā)階段

          正常開發(fā)代碼,無需有任何額外操作。

          構建階段

          publish-tag


          新增一個git tag,以p-開頭,意為publish。每次發(fā)布都有一個tag標記,格式為p-201911111001-lvdabao.標記發(fā)布時間與發(fā)布者。構建完成并同步cdn成功后,會將該tag同步到git倉庫。


          manifest.json


          manifest.json是webpack構建完畢后的文件清單,可以用webpack-manifest-plugin插件生成。如有特殊需求也可以自己編寫。我們是自己編寫,并在動態(tài)渲染首頁HTML時讀取清單內容并輸出script標簽。


          每次構建生成的文件名稱是這樣的格式:manifest-p-201911111001-lvdabao.json,這樣每次發(fā)布都生成對應tag命名的manifest.json文件。


          啟動服務時可以一次讀取到內存中,并不是處理每個請求都讀一下文件,所以不必擔心性能。


          獲取上次發(fā)布的版本信息


          我們是用publish-tag來標識版本號的,只要拿到上次發(fā)布時的tag,就能取到對應的manifest.json文件。所以構建的最后一步就是把上一版的manifest.json文件從cdn源機器取到當前構建后的dist目錄下,為后續(xù)服務啟動時使用。


          取上次的tag也很簡單,一個git命令搞定:git tag --sort=-taggerdate | grep "^p-.*" | head -n 1


          容錯機制


          如果上次發(fā)布的版本有重大問題,不能作為stable版使用,有什么辦法呢?

          所以我們增加了一個額外流程,允許構建的時候傳入環(huán)境變量,指定stable tag。這樣在獲取stable版本信息時,優(yōu)先取環(huán)境變量中指定的。

          部署階段

          部署跟普通流程沒什么區(qū)別,將dist目錄發(fā)布到目標機器就行了。每次部署的dist文件包含以下:


          • beta版的manifest.json文件

          • beta版的資源文件

          • stable版的manifest.json文件

          啟動服務

          啟動服務時我們需要干兩件事情:


          1. 把兩個manifest.json文件讀到內存中,供分流時使用

          2. 自動修改放量配置,將新版本比例改為

          放量配置

          上面提到了放量配置,這個是放在單獨的配置系統(tǒng)中的,當然簡單點放在服務端也是可以的。用途就是根據(jù)當前用戶的uuid,來確定用戶該使用哪個版本的資源。


          配置內容也及其簡單:


          {
          ????percent:?10
          }


          percent即是beta版的放量比例,10表示10%的用戶使用beta版。全量的時候手動改為100就行啦。


          因為啟動服務的時候會自動將percent改為0,所以每次發(fā)布完后,我們只需根據(jù)放量節(jié)奏逐步擴大percent的值就好。


          處理請求

          萬事具備,我們在處理請求的時候,就很easy了。只需獲取當前用戶的uuid,node層通過RPC調用獲取到放量配置,通過分流策略來計算應該使用哪個版本的資源。


          我們的首頁是動態(tài)輸出的(SSR),拿到分流策略得出的tag,把相應的manifest.json中的文件輸出,這樣就控制了哪部分用戶使用beta版本。

          分流策略

          最后再談談分流策略,這塊也是有很多細節(jié)的。分流策略要做的核心工作:


          1. 根據(jù)放量配置來決定當前用戶應使用的資源版本

          2. 確保用戶的分流路線穩(wěn)定,即下次請求頁面應與上次的分流結果一致

          3. 新版本發(fā)布或放量比例變化時,重新分流


          首先,放量配置只有一個百分比數(shù)字,我們需要把uuid散列化,即把uuid字符串對應到0-99間固定的數(shù)字。算法可以有很多,我們選一種簡單的,取每個字符的ASCII碼相加,然后再除100取余。偽代碼:


          for?(i?=?0;?i?????hash?+=?uuid.charCodeAt(i);
          }


          取到的這個hash就可以與放量百分比比較,在范圍內就使用beta版。


          另外一個比較麻煩的事情是第2點,為了讓用戶下次訪問的時候能夠跟首次的分流一致,我們需要把首次分流的結果保存在cookie中。當請求來的時候先分析cookie中的版本信息,如果可用則優(yōu)先用cookie。不可用的話清掉cookie,再去計算分流。


          那么既然uuid的散列算法能保證hash值穩(wěn)定,每次都用uuid計算不行嗎?原因就是我們訪問環(huán)境的特殊,uuid的穩(wěn)定性不能保證,相對來說還是cookie更穩(wěn)定。這個看項目吧,如果你的項目uuid穩(wěn)定,那可以省去用cookie。

          總結

          以上就是灰度發(fā)布方案的核心內容啦,相關的代碼細節(jié)不贅述,有讀者朋友感興趣可以留言探討。


          通過這套方案我們實現(xiàn)了以用戶維度進行分組的灰度發(fā)布,并且整個流程足夠自動化,業(yè)務開發(fā)無感知,需要手動操作的只有修改放量配置。


          有朋友可能想說,你這個方案和ABTest很相似啊!其實ABTest和本方案的差別主要有:


          1. 需要同時上線AB兩套新代碼

          2. 最終會丟棄其中一套代碼


          盡管看起來差別不大,但ABTest方案的構建、部署、分流控制都會有所區(qū)別。


          當然,如果我們把ABTest退一步,認為stable版是A,新上線代碼是B,那么將本方案改造成ABTest方案也很容易。


          分享前端好文,缺個?在看?6b20a7f480d4aa2902509dce4dd4ff7a.webp

          瀏覽 58
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  北条麻妃在线一区二区三区 | 大香蕉久久久久 | 亚洲视频黄色 | 淫色大吊人妖乱伦视频 | 波多野吉衣高清无码 |