免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
微前端架構(gòu):如何由內(nèi)而外取代單體架構(gòu)
作者|Zack Jackson
譯者|核子可樂、無明
編輯|王文婧
如何利用微前端技術(shù)實(shí)現(xiàn)單體應(yīng)用程序的現(xiàn)代化改造?在本篇教程中,我們將探討如何將前端從單體架構(gòu)當(dāng)中剝離出來,并快速完成微前端架構(gòu)遷移。本文作者將結(jié)合個人項(xiàng)目實(shí)踐經(jīng)驗(yàn)為大家介紹心得。
問題所在

我們假設(shè)有這么一個單體代碼庫,它使用了某種后端模板引擎或者系統(tǒng)(例如 EJS 或者 ERB),但沒有認(rèn)真考慮前端的設(shè)計需求?;蛘吒愀獾氖?,前端的開發(fā)早于 SPA 的出現(xiàn),或者還可能使用了類似 Ruby on Rails 那樣的框架。因此,JavaScript 文件(例如.js.erb 文件或 AEM 片段等等)中可能包含了后端變量。這種粗制濫造且各組件間緊密耦合的代碼庫幾乎無法進(jìn)行現(xiàn)代化升級。

我們當(dāng)然希望不要再在這個單體系統(tǒng)中開發(fā)前端代碼,我們希望轉(zhuǎn)向更加 JavaScript 化的生態(tài)系統(tǒng)——但具體該怎么做?

大多數(shù)企業(yè)都負(fù)擔(dān)不起(或者不愿負(fù)擔(dān))這種因工具淘汰帶來的重寫成本與停機(jī)時間。功能的演進(jìn)需要開發(fā)的支持,但要保持同樣的速度開發(fā)這些功能顯然越來越困難。

正因如此,我們應(yīng)該通過一種漸進(jìn)且平滑的方式將單體逐步拆分為更多較小的部分,同時保證不讓業(yè)務(wù)發(fā)生中斷。

說來簡單,但單體架構(gòu)的拆分過程相當(dāng)棘手。在進(jìn)行前端遷移時需要為支持 JavaScript 的應(yīng)用程序規(guī)劃和開發(fā)新 API,拆分就變得尤為困難。

在等待新 API 開發(fā)和發(fā)布的過程中,前端迭代開發(fā)、微前端(MFE)實(shí)現(xiàn)和團(tuán)隊(duì)的自主行動都將陷入僵局。但真的要這樣子嗎?錯!我們可以對前端和后端進(jìn)行解耦,讓它們齊頭并進(jìn)。

Zack Jackson — ScriptedAlchemy

下面將介紹一種方法,它能夠順利解耦前端,并將其移植成具有 SSR 的獨(dú)立 MFE。如此一來,團(tuán)隊(duì)不再需要等待后端 API 被拆分成微服務(wù)或者等待后端 API 可用。這個方法叫作“由內(nèi)而外替換單體”。

阻礙因素

微前端通常包含以下兩大重要依賴項(xiàng):

1) 認(rèn)證;

2) 提供給應(yīng)用程序的數(shù)據(jù),在瀏覽器端和在服務(wù)器端渲染(SSR)期間。

根據(jù)我的個人經(jīng)驗(yàn),無論你的遺留系統(tǒng)屬于 Rails、Java 還是.Net,用戶身份認(rèn)證一直是最難與單體后端進(jìn)行剝離的部分。

將單體作為布局引擎

MFE 有多種不同的架構(gòu)規(guī)范。本文將重點(diǎn)介紹其中一種,即在后端微服務(wù)中非常流行的一個版本——LOSA(Lots Of Small Applications,大量小應(yīng)用)。對于“由內(nèi)而外”遷移來說,這是最理想的選擇。

流經(jīng)單體的 LOSA 請求 / 響應(yīng)流

LOSA 應(yīng)用(通常為微前端)屬于獨(dú)立的 Node.js 服務(wù),能夠在服務(wù)器端渲染網(wǎng)頁的一部分或者某些片段。每個頁面可以由多個 LOSA 服務(wù)組成。這些應(yīng)用程序 / 微前端單獨(dú)進(jìn)行構(gòu)建、部署,并運(yùn)行在容器中。

上圖所示為同一頁面采用了三種不同的渲染方式,演示了一個增量遷移的過程。先是單體渲染頁面,再過渡到 LOSA 微前端,然后變成垂直的微前端。最后,單體被徹底替換掉。

當(dāng)然,單體仍然負(fù)責(zé)處理 HTTP 請求,并將最終響應(yīng)發(fā)送至客戶端。微前端可以放在集群的防火墻后面——僅提供給遺留系統(tǒng)使用,直到 API 網(wǎng)關(guān)和用戶身份認(rèn)證機(jī)制剝離完成(或者至少已經(jīng)轉(zhuǎn)化為 API 端點(diǎn))。在此期間,我們不需要做太多的改動。

渲染流程

下圖展示了遷移后的請求 / 響應(yīng)流程。

首先,發(fā)出一個請求:
GET/POST 'https://MFEwebsite.com/parts/header?format=json

渲染頁面內(nèi)容需要各類數(shù)據(jù),那些無法從已解耦端點(diǎn)查詢到的“缺失”信息可以在請求期間以 props 的形式發(fā)送給 MFE。請求會經(jīng)過一系列中間件,這些中間件負(fù)責(zé)渲染 React 應(yīng)用程序,然后調(diào)用已解耦的 API,并將響應(yīng)結(jié)果以 props 的形式返回。這些 props 最終將組成 window.INITIAL_STATE。

代 碼

關(guān)于模板功能或者過濾器的實(shí)現(xiàn)方法,我向大家推薦 Hypernova。不過我自己并沒用過,我已經(jīng)習(xí)慣了一切自己動手,并在 Rails、Node 以及 PHP 后端中實(shí)現(xiàn)了類似的機(jī)制。但考慮到各類后端平臺都有自己的特點(diǎn),所以這里我就用 Hypernova 作為示例向大家講解。

下面使用 express 實(shí)現(xiàn) MFE 渲染端點(diǎn):

來自另一個系統(tǒng)的請求(在這里就是那個單體):
GET/POST 'https://MFEwebsite.com/parts/header?format=json
{
   html: '<div> ... </div>',
   css: '/static/header.3042u3298423.css',
   js: '/static/header.idhf93hf23iu.js',
   initial_state: {items:[...]}
}
用于處理響應(yīng)的中間件:
export function exampleRenderAPIware(req, res) {
  const renderedMarkup = renderHTMLpage(
    req,
    this.index,
    intial_state,
  );
  asyncRender.then(() => {
    const responseObject = {
      html: renderedMarkup,
      initial_state,
      js: jsResource,
      css: cssResource,
    };
    res.status(200).end(JSON.stringify(responseObject));
  });
}

發(fā)出這些初始 POST 請求的控制器也需要處理響應(yīng)結(jié)果,將 JS 與 CSS 放在正確的位置,最后在遺留模板的對應(yīng)位置渲染 React。之前通常由其他控制器負(fù)責(zé)處理的資產(chǎn)現(xiàn)在需要負(fù)責(zé)將腳本與樣式注入到遺留標(biāo)頭與 body 標(biāo)簽的底部。請注意,單體仍然被作為布局引擎。我們也在替換其他部分,并以 React SSR 方式添加新功能。最終,這些 LOSA 應(yīng)用將通過一個 MFE(或者借助 Webpack 黑魔法,我自己開發(fā)了 webpack-external-import)整合在一起。

如何從模板數(shù)據(jù)遷移至新 API?

在遷移中,解耦并上線新的 API 到底會帶來怎樣的影響?

之前,在單體把數(shù)據(jù)傳給 MFE 時,express 訪問 HTTP 的請求正文。而現(xiàn)在,express 向 API 異步獲取數(shù)據(jù)。雖然數(shù)據(jù)格式可能會發(fā)生變化,但 React 仍然能夠正確獲取到 props。

性能差異

與舊單體相比,LOSA 架構(gòu)的性能還不夠好,通常需要 400 到 600 毫秒才能渲染出頁面的特定部分。我們采用了異步 Worker 結(jié)構(gòu),這樣就可以同時請求多項(xiàng)服務(wù)來渲染應(yīng)用程序的不同部分(而不是渲染單個應(yīng)用)。但這種作法提高了應(yīng)用下線的難度,因?yàn)椤吧a(chǎn)故障”會導(dǎo)致側(cè)邊欄或頁腳部分長時間缺失。因此,進(jìn)一步拆分才是最好的選擇。

我所說的 LOSA 異步 Worker 是這樣的:我們使用大量的 Node 服務(wù),每一個服務(wù)負(fù)責(zé)渲染頁面的一個或多個組件。

遺留控制器(圖中的灰色齒輪部分)可以將視圖數(shù)據(jù)轉(zhuǎn)給 POST 請求,而非后端模板引擎?;厥諗?shù)據(jù)機(jī)制則能夠幫助后端減少支持負(fù)擔(dān)。由于無需做出重大修改,后端開發(fā)人員能夠騰出時間,專注于解耦數(shù)據(jù)服務(wù),而前端也可以進(jìn)行獨(dú)立的開發(fā)。

視圖數(shù)據(jù)被發(fā)送給了外部的 React 服務(wù),而響應(yīng)消息(包含了 HTML、樣式表、初始狀態(tài)以及 CSS URL)則被發(fā)送給后端模板引擎?,F(xiàn)在,模板引擎只需要渲染 POST 請求所對應(yīng)的響應(yīng),從而將視圖或視圖的一部分與原有單體剝離開來。

React 渲染時間

React 真的很慢!SSR 也不怎么快——因此新的 LOSA 架構(gòu)解決方案無法帶來理想的性能表現(xiàn)。我們的解決方案是:在 React 內(nèi)部進(jìn)行片段緩存。

  • 黃色:無 React 片段緩存——端到端(400 毫秒左右)

  • 深紫:有 React 片段緩存——端到端(150 毫秒左右)

  • 橙色:全優(yōu)化架構(gòu)(20 毫秒左右)

  • 綠色(底部):來自后端的原生片段緩存

React 優(yōu)化工作相當(dāng)復(fù)雜,受篇幅所限,恐怕只能另起一篇文章詳加說明了??傊?,Graphana 數(shù)據(jù)顯示,我們至少將渲染性能提高了一倍,不過輪循時間仍然很長。盡管 React 已經(jīng)能夠在內(nèi)部快速完成渲染,但 150 毫秒的端到端時間還沒有達(dá)到我們的預(yù)期。在下一篇文章中,我們將具體聊聊片段后端與片段緩存。

渲染時間 VS 輪回時間

渲染時間一直是個麻煩事,即使是在 React 中采用了片段緩存之后,性能仍然無法令人滿意。令我感到失望的是,雖然 Node.js 內(nèi)部的渲染速度很快(約 20 毫秒),但整個流程仍然需要 140 到 200 毫秒才能完成。

瓶頸所在

  1. JSON 大小,特別是初始應(yīng)用狀態(tài)——即渲染頁面所需要的最少 state。我們不再在初始渲染中放置太多字符串化的 state,只發(fā)送足夠讓 React 完成渲染并讓折疊組件變得可交互的必要 state。
  2. 需要渲染的 DOM 節(jié)點(diǎn)數(shù)量——不再將代碼放在無用的 DIV 中,只需要給它們加個 class。利用 HTML 的語義特性以及 CSS 的級聯(lián)效果,我們可以少寫一些 HTML 代碼,這樣也就減少了 React.createComponent 函數(shù)的生成。
  3. 垃圾回收——我們將在下一篇文章中討論更多細(xì)節(jié)。
  4. 速度由數(shù)據(jù)服務(wù)決定——在中間層使用 Redis。很多朋友認(rèn)為“緩存失效問題難以解決”,我建議各位認(rèn)真考慮一下事件溯源,或者我們可以使用 CQRS 與異步 Worker 來處理讀寫操作。
  5. 單體架構(gòu)與 MFE 之間的 HTTP 開銷——也就是 gRPC、CQRS、UDP 以及 Protobuf。二者之間的通信應(yīng)該通過內(nèi)部 Kubernetes 網(wǎng)絡(luò)進(jìn)行。POST 速度很慢,但也不是不能用。遇到問題時個別處理即可。

如何提升后端渲染性能

簡單來說,模板化、片段緩存與 gRPC/CQRS,移除 JSON 中臃腫的數(shù)據(jù)。React 在服務(wù)器端速度較慢,但請記住,一切拆分都只會讓速度變得稍慢,而不是更快。

伸縮問題如何解決?
對于一切解決方案,如果不能在規(guī)?;瘓鼍跋聦?shí)現(xiàn)良好的成本效益,那么都將只是空談。我們絕對不能容忍天文數(shù)字級的運(yùn)營成本或者糟糕的性價比。大規(guī)模且廉價的解決方案才是好的解決方案。下面來看幾點(diǎn)容易被忽視的成本要素:
  1. 昂貴的第三方服務(wù)費(fèi)用;
  2. 更多 / 更大的容器環(huán)境;
  3. 由于性能不佳而導(dǎo)致的收入損失;
  4. 由于兩個分支無法同時被合并到 master,因此單體架構(gòu)會導(dǎo)致發(fā)布周期或部署流程阻塞;
  5. 開發(fā)人員在風(fēng)險較低的環(huán)境中可以快速行動,業(yè)務(wù)人員能夠?qū)⑿孪敕ㄍ葡蚴袌?,并對出現(xiàn)問題的部分及時回滾——快速行動的能力正是實(shí)現(xiàn)高成本效益的必要前提。

最終結(jié)果

流量: 1000 萬次渲染 / 天

資源分配:
  • 實(shí)例: 5

  • 內(nèi)存: 100mi (100 MB 內(nèi)存)

  • CPU: 100 (單核)

  • 最大 CPU 使用率閾值: 65%

  • 響應(yīng)時間:20 至 25 毫秒

  • DOM 復(fù)雜度:高

  • 響應(yīng)時間縮短了 95%

  • 綠色:后端渲染時間

  • 藍(lán)色:使用了片段緩存和 state 優(yōu)化的 React

我的單線程 JavaScript 應(yīng)用程序要比使用完整片段緩存的多線程后端系統(tǒng)更快。

原文鏈接:https://levelup.gitconnected.com/micro-frontend-architecture-replacing-a-monolith-from-the-inside-out-61f60d2e14c1

活動推薦

偶發(fā) bug 大大增加了排查的成本,復(fù)現(xiàn)也變成了所有研發(fā)心中的痛。在即將召開的 ArchSummit 全球架構(gòu)師峰會(北京站)上,貝殼找房基礎(chǔ)架構(gòu)中心前端架構(gòu)委員會專家陳辰將為大家?guī)碡悮ぷ匝斜O(jiān)控平臺燈塔之外的另一項(xiàng)目——時光機(jī),揭秘如何利用時光機(jī)讓偶現(xiàn) bug 無所遁形。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
2015年值得關(guān)注的幾個WEB技術(shù)
新一波JavaScript Web框架
和chatgpt學(xué)架構(gòu)01-搭建項(xiàng)目腳手架
2021 年最佳 JavaScript 框架排名
你真的懂前后端分離嗎?
中臺微服務(wù)了,那前端如何進(jìn)行架構(gòu)設(shè)計?
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服