【數據中台商業化】數據中台微前端實踐

来源:https://www.cnblogs.com/Jcloud/archive/2023/04/21/17339332.html
-Advertisement-
Play Games

我們設計目前的門戶基座,可以快速瀏覽各個平臺,同時串聯數據開發與管理的工作,減少用戶的試錯成本,提升工作效率。 ...


作者:京東科技 陳雲飛

一,需求背景

1 業務背景

在以往的業務場景中,用戶進入五花八門的菜單體系中,往往會產生迷茫情緒,難以理解平臺名稱及具體作用,導致數據開發與管理學習成本較高,降低工作效率。為此我們整合從數據接入,數據開發,數據管理的全鏈路流程,期望讓用戶體驗一站式數據開發與管理的便捷性;並提供不同業務場景,方便根據業務場景進行進一步數據開發與管理工作,為數據應用平臺打下夯實規範的數據基礎,方便用戶在數據平臺里,對於數據開發和數據應用進行便捷性的切換,因此我們設計目前的門戶基座,可以快速瀏覽各個平臺,同時串聯數據開發與管理的工作,減少用戶的試錯成本,提升工作效率。

2 標品需求

基座子-項目交互簡圖如圖1;

1,基座的業務頁面比較簡單,主要包含:頂部邊欄、左側邊欄、公共子菜單、頂級平臺菜單;

2,點擊左上角圖標,顯示頂級平臺菜單,點擊平臺,在基座左側邊欄動態顯示平臺一級菜單;

3,點擊基座左側邊欄,在公共子菜單,動態顯示一級菜單下邊的二級、三級菜單;

4,點擊基座左側邊欄或者公共子菜單,需要基座調度,在子項目區域正確載入子項目及子項目頁面;

圖 1

數據中台新門戶基座要接入老數據平臺一、老數據平臺二等 多平臺的前端項目,並且原有前端子項目在門戶基座呈現任意子項目、任意子項目頁面 任意混搭的需求;新門戶要接入的項目關係詳情如圖2;

圖 2

3 數據中台融合;

數據中台融合指的是京東體系內,其他對外獨立交付的數據中台,比如京東工業、京東城市等項目;數據中台商業化的子項目不僅在新門戶容器內,也可以按需打包進其他數據中台容器;下麵簡稱 數據中台融合;

二,微前端技術調研

原有數據中台接入子應用的方式有多種:iframe 嵌套、@weus 微應用、鏈接跳轉等;

1 iframe 存在問題:

• url 不同步。瀏覽器刷新 iframe url 狀態丟失、後退前進按鈕無法使用。

• UI 不同步,DOM 結構不共用。想象一下屏幕右下角 1/4 的 iframe 里來一個帶遮罩層的彈框,同時我們要求這個彈框要瀏覽器居中顯示,還要瀏覽器 resize 時自動居中..

• 全局上下文完全隔離,記憶體變數不共用。iframe 內外系統的通信、數據同步等需求,主應用的 cookie 要透傳到根功能變數名稱都不同的子應用中實現免登效果。

• 慢。每次子應用進入都是一次瀏覽器上下文重建、資源重新載入的過程。

2 weus 存在問題:

•weus 是京東內部研發已經不再維護了,如果有新的問題需要自己解決,對微前端有新需求也需要自己去實現;

•weus 沒有嚴格的 css 沙箱、js 沙箱,而在我們的需求中,沙箱機制是剛需,我們要接入的子項目在 window 上掛在哪些變數,無法通過規範做到強有力的制約(因為要接入的項目是已經寫完了)

•weus 在微前端功能實現,沒有qiankun 豐富健全,比如全局狀態管理、雖然 weus 實現了子應用的預載入,但是比較機械,是把所有註冊的子應用都緩存,實際可能不需要,qiankun 就比較靈活可以根據需要手動緩存等;

3 鏈接跳轉

鏈接跳轉,指的是點擊一個菜單,跳轉到另一個頁面。這種方式不符合 “一站式 ”大數據平臺產品定位;

4 最終結論

通過幾種實現方式的對比,最終決定以 qiankun 微前端為基礎,結合我們的實際業務場景,通過許可權菜單樹 和 子項目關聯來實現基座對子項目的調度,具體方案請參照 三,基座技術方案詳細描述;

三,技術方案詳細描述;

1 名詞解釋

跨子項目跳轉

指的是子項目沒通過基座自行跳轉,基座此時需要根據 url 匹配正確的基座顯示;

觸發節點

點擊菜單,菜單對應的節點即為觸發節點,跨子項目跳轉(刷新頁面)沒有觸發節點,以跳轉後url 對應的頁面節點為觸發節點;

頁面節點

許可權菜單樹中,掛載了子項目頁面的節點

門戶節點

狹義指的是,當前頁面節點對應的公共子菜單父級節點;廣義指的是通過頁面節點向父系節點查詢,最終確認公共子菜單、基座邊欄的顯示,並通過頁面節點確定菜單高亮等行為;

第一子系節點

指的是在由觸發節點查頁面節點時,只關註子節點中的第一個,如果當前節點的第一個節點不是頁面節點,繼續在孫子節點的第一個,直到節點類型為頁面節點為止;

調度引擎

指的是在基座中,對許可權樹數據處理,接收基座業務層調度,通過對許可權樹遍歷、查詢操作對業務層輸出運算結果的一個抽象分層;

2 整體流程圖

如圖3 為基座技術方案的整體流程圖,下麵詳細介紹

圖 3

3 技術方案-分步描述

第 1 步,配置許可權菜單樹,關聯子項目頁面

•如圖 3 所示,首先會在許可權中心配置許可權菜單樹,許可權菜單樹有很多級,比如一級平臺,二級平臺,二級平臺一級菜單,二級菜單等,三級菜單等;

•然後需要在菜單樹上,掛在子項目的頁面,子項目頁面的一些許可權按鈕等;

•最後許可權中心對不同的用戶賦予許可權菜單樹的子集;

第 2 步,基座菜單樹數據處理;

•基座從介面拿到許可權菜單樹關聯頁面數據後,觸發調度引擎初始化、並把基座的業務更新函數傳給調度引擎;

•基座獲取到菜單樹以後,廣度優先演算法(如圖4)遍歷整個樹結構,並建立節點間父子關聯關係。根據節點是否掛載了子項目頁面定義前端節點類型 ;最終形成圖 5 的數據;

•在樹遍歷過程中,會統一在基座左側邊欄這一層級的節點,做一個門戶節點的標記;

圖4

•如圖 5 所示,前端調度關係中,把許可權菜單樹分成 兩種節點類型,掛載了子項目頁面的節點,定義為頁面節點。另一種沒掛載子項目頁面的節點,定義為分組節點;在基座調度中,不關心許可權按鈕節點,在數據處理中,頁面節點就是整個許可權菜單樹的葉子節點;

圖 5

第 3 步,點擊基座邊欄或公共子菜單

•點擊基座邊欄,觸發點擊菜單流程,點擊的節點即為 “觸發節點”;

•由觸發節點,向第一子系節點查頁面節點,查頁面節點同時,會同時匹配門戶節點;

•沒有匹配到門戶節點,由觸發節點向父系節點匹配門戶節點;

第 4 步,刷新頁面或跨子項目跳轉

•這時沒有直接的觸發節點,只能通過 url 上的標識和菜單樹上的頁面節點進行匹配

•匹配到頁面節點以後,由頁面節點向父系節點查門戶節點;

第 5 步,通過門戶節點輸出 “運算結果”

•這裡的運算結果主要包含:基座左側邊欄、公共子菜單菜單樹列表、菜單高亮、產品平臺名稱等一系列基座需要正確顯示所需要的數據;

•基座調度引擎,根據觸發調度的類型;如果是點擊菜單觸發會執行 切換頁面操作,刷新和跨子項目跳轉則不需要觸發;

第 6 步,基座業務層執行運算結果;

•基座調度引擎,在接收基座業務層調度指令後,通過對圖 5 許可權樹的遍歷、查詢操作,最終獲取運算結果;

• 調用基座業務層的更新函數,執行運算結果,到此基座調度流程結束;

四,基座-子項目結構通信圖

1 基座分為業務層、調度引擎兩部分;

•基座業務層主要包含:左側邊欄、頂部邊欄、頂級平臺菜單等 UI顯示;

•基座調度層,以 qiankun 微前端為基礎,豐富擴展了許可權樹數據處理、調度運算、雙向通信、子項目分組分步預載入策略等;

2 基座子項目通信和路由調度

•基座在執行主題切換時候,通過 qiankun 的 setGlobalState 通知子項目;子項目在綁定項目空間等特定需求時,通過調度引擎封裝的 eventCenter 和基座反向通信;

•跨子項目跳轉,子項目會自行觸發 pushState,點擊基座菜單跳轉流程,由調度引擎觸發 pushState 觸達

• qiankun 的 pushSate 劫持策略,觸發 popstate 子項目頁面因此觸發更新;

圖 6

3 路由劫持策略原理

基座調度引擎通過監聽 popstate 來獲取刷新、跨子項目跳轉的指令,從而觸發調度流程;以下為原理解析:

•以 Vue 為例,Vue 通過 主動觸發 pushState、replaceState 或者監聽 popstate 變化觸發頁面發生變化;

•但是跨子項目跳轉,執行 pushState 並沒有觸發 popState 基座調度引擎又怎麼能監聽到呢?

•通過閱讀 qiankun 中依賴的庫 single-spa 的源碼,navigation 模塊劫持了 pushstate 方法,只要觸發 pushstate,就會觸發 popstate 事件,關鍵代碼如下所示:

function patchedUpdateState(updateState, methodName) {
  return function () {
    const urlBefore = window.location.href;
    const result = updateState.apply(this, arguments);
    const urlAfter = window.location.href;


    if (!urlRerouteOnly || urlBefore !== urlAfter) {
      if (isStarted()) {
        window.dispatchEvent(
          createPopStateEvent(window.history.state, methodName)
        );
      } else {
        reroute([]);
      }
    }
    return result;
  };
}
window.history.pushState = patchedUpdateState(
   window.history.pushState,
   "pushState"
);

五,基於 qiankun 功能擴展:

1 沙箱隔離

js 沙箱利用 qiankun 沙箱機制;

css 沙箱,qiankun 的 css 沙箱不健全;我們接入的又是老項目,目前的策略是 :

•基座通過特殊命名空間 .susceptor、element-ui 通過 .spr 跟子項目隔離;

•子項目通過特殊命名空間,例如 .datacenter-xxx 跟基座隔離

•子項目對 .el- 不執行隔離,目的是為了統一控制佈局、主題,同時做性能優化;

2 通信機制

基座和子項目,屬於典型的主從結構,採用單向數據流通信;為了滿足特殊場景子項目跟基座通信需求,在 qiankun 的通信基礎上,封裝了 eventCenter 僅用於 子項目 跟基座通信;

•基座 -> 子項目,通過qiankun 的 onGlobalStateChange 通信

•子項目 -> 基座,通過 subActions 封裝的 eventCenter 通信

3 分組、分步、動態預載入機制

目前標品基座已經載入了 30多個前端子項目,這麼多前端子項目在首個子項目掛載後執行預載入,有可能會阻塞正常頁面訪問;

分組指的是,通過產品劃定的平臺,只有切換到當前平臺才會載入到當前平臺的子項目;

分步指的是,當前平臺子項目過多時,一次預載入少量子項目,分多次預載入;

動態指的是,基座在首個子項目掛載後,會檢測網速,只有網速良好時才會執行預載入;

4 跨子項目跳轉

跨子項目跳轉的背景在於 BDP 一站式開發與管理平臺,是一個大產品,數據規劃、數據集成 等是其中的模塊;模塊之間存在一些跳轉,對於前端就是跨子項目跳轉;

我們目前的跨子項目跳轉,由 subActions 封裝,抹平了標品基座 和 數據中台融合容器的區別;

基座跳轉邏輯如下:

crossAppJump: ({ subApp='', path= '', paramsStr='', target= ''})=> {
      let jumpUrl = `/susceptor/${subApp}${path}`
      if(paramsStr){
        jumpUrl = `${jumpUrl}${paramsStr}`
      }
      if(target === '_blank'){
        window.open(`${location.origin}${jumpUrl}`)
      } else {
        window.history.pushState({ portalPushState: true }, null, jumpUrl);
      }
  },

數據中台融合跳轉邏輯如下:

 crossAppJump: ({ subApp='', path= '', paramsStr='', target= ''})=> {
      let jumpUrl = `/${subApp}${path}`
      window.__datafuse_jssdk__.crossAppJumpFnGetter({
        path: jumpUrl,
        paramsStr,
        target
      })();
}

5,介面訪問及登錄鑒權;

由於微前端的技術形態,子項目在基座中載入實質是基座容器的 一段 html,所有介面均是以基座的 功能變數名稱進行介面轉發;由因為數據中台融合,所以子項目請求後端介面均是以 /api/datacenter/項目名 開頭;

通過以下 nginx 示例,我們把基座、子項目 的頁面訪問、介面訪問鏈路 說明白;

# proxy.conf 示例(已做脫敏處理,均不是項目升級名稱)
server {
    listen                80;
    server_name           unify.external.dadacenter;
    charset utf-8;
   location /sub-app{
        alias  /export/web/sub-app-web;
        try_files $uri $uri/ /index.html =404;
   }
   location /api/datacenter/subapp {
        proxy_pass   http://server-sup-app/;
   }
   location /susceptor{
      alias  /export/web/susceptor;     on;
      try_files $uri $uri/ /index.html =404;
   }
   location /api{
        proxy_pass  http://sever-api/;
  }
}


# server.conf 示例(已做脫敏處理,均不是實際項目)
upstream server-sup-app{
    server 111.112.113.114:10001;
}
upstream sever-api{
    server 111.112.113.114:1000;
}

鑒權,前端不需要開發,但是需要知道,後端是通過頂級功能變數名稱種 cookie 鑒權的;例如:unify.external.bigdata 測試環境是在 .external.bigdatao 功能變數名稱下,這也是為什麼本地開發需要配置 host:127.0.01 loca.external.dadacenter ;

六,寫在最後,不忘初心

本節提供兩個圖, 對上文介紹的微前端實踐,有進一步的能力提升,有感興趣的同學歡迎一起討論;

1,整體流程圖;

如圖 6 所示,配置流程:配置許可權菜單樹,然後配置子項目-子項目頁面兩級;最後把許可權菜單樹 和 子項目-子項目頁面關聯起來,形成如圖 7 的許可權樹-子項目關聯數據模型;

基座兩個調度流程,跟上文類似,但是多了子項目維度,基座在載入子項目的時候,就可以把子項目 在許可權樹的 許可權按鈕信息全部給到子項目;

圖 6

2 許可權菜單樹模型;

上文介紹的基座調度流程是簡化後的版本,項目節點只有 分組節點、頁面節點;但是從能力層缺失了 子項目維度;在設計之初,如圖 7 所示:項目節點包含了 分組節點、子項目節點、子項目頁面節點、頁面節點 4種節點類型;

圖 7


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 華為HMS生態攜手流媒體平臺Viu,為海外消費者打造精品移動娛樂應用體驗,並助力提升流量變現能力。Viu在中東非、東南亞等16個國家及地區提供廣告合作和付費會員服務,支持優質視頻內容高清點播和直播。自2019年起,Viu在中東非區域與華為HMS生態開展一系列緊密合作,併在2022年實現47%的用戶增 ...
  • 和其他平臺類似,Android 中 View 的佈局是一個樹形結構,各個 ViewGroup 和 View 是按樹形結構嵌套佈局的,從而會出現用戶觸摸的位置坐標可能會落在多個 View 的範圍內,這樣就不知道哪個 View 來響應這個事件,為瞭解決這一問題,就出現了事件分發機制。 ...
  • 在成功搭建好DRF(Django rest framework)的Blog的backend後,昨天開始搭建Vue3+axios+pinia+element_plus的前臺服務. 開始一切順利,到第一個axios的get處理的時候,出現了錯誤. axios相關的代碼如下: 載入vue-axios和ax ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 概念介紹 深拷貝:在堆記憶體中重新開闢一個存儲空間,完全克隆一個一模一樣的對象 淺拷貝:不在堆記憶體中重新開闢空間,只複製棧記憶體中的引用地址。本質上兩個對象(數組)依然指向同一塊存儲空間 第一種:遞歸方式(推薦,項目中最安全最常用) 使用遞歸 ...
  • 使用.env加尾碼的方式來建立某個模式下的環境變數, 例如:項目根目錄新建兩個環境變數文件(development開發環境和production生產環境): .env.development .env.production 在新建的兩個環境變數文件中設置相同的環境變數名: VUE_APP_BASE_ ...
  • 一、簡單瞭解JS 1. JavaScript(簡稱JS)是作為開發Web頁面的腳本語言。 2. JS是從1995年由網景公司的布蘭德開發。 3. JavaScript的標準是ECMAScript。 4. JS代碼是從上往下執行的。 二、變數 1. 變數名的值可以重覆賦值(值可以修改),變數可以重覆聲 ...
  • HTML input type="number" 隱藏預設的步進箭頭 number 類型的 <input> 元素用於讓用戶輸入一個數字,其包括內置驗證以拒絕非數字輸入。 瀏覽器可能會選擇提供步進箭頭,讓用戶可以使用滑鼠增加和減少輸入的值,或者只需用指尖敲擊即可。但有些場景需要隱藏預設的步進箭頭。 要 ...
  • devServer 是一個用於配置開發伺服器的選項對象。它可以用來配置伺服器的各種選項,例如代理,埠號,HTTPS 等。 以下是一些常用的 devServer 參數和設置: port:指定開發伺服器的埠號,預設為 8080。 host:指定開發伺服器的主機名,預設為 localhost。 htt ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...