前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

傳統(tǒng)前端業(yè)務(wù)通常會根據(jù)業(yè)務(wù)線集成在一個站點(diǎn)上,隨著業(yè)務(wù)復(fù)雜度上升贯溅,包體積會迅速變的過大拄氯。為了適應(yīng)這個變化往往需要更多的開發(fā)者、更細(xì)粒度的團(tuán)隊(duì)組織它浅。分組開發(fā)時大家的模塊解耦到各自完成译柏,上線時糅合在一起運(yùn)行,產(chǎn)生出層出不窮的分支合并姐霍、代碼回滾鄙麦,都會造成合作效率的驟降。這正是頭條號平臺在 17 年時面臨的問題镊折。

過大的代碼集合還會造成發(fā)布頻繁黔衡,每個業(yè)務(wù)分支和功能點(diǎn)都有一定的更新頻率,如果以傳統(tǒng)的獨(dú)石系統(tǒng)開發(fā)腌乡、驗(yàn)證和上線盟劫,每一個業(yè)務(wù)都會讓項(xiàng)目所有一起升級、測試和上線与纽,發(fā)布頻率的總和會非常高侣签、非常頻繁。如果不解除原有的耦合會徹底失去響應(yīng)能力急迂。

更進(jìn)一步來看以如此之高的上線頻率影所、版本迭代速度,開發(fā)者極難追溯哪個版本對應(yīng)哪個改動僚碎。

字節(jié)跳動微服務(wù)前端解決方案為應(yīng)對以上挑戰(zhàn)而生猴娩。經(jīng)過幾年發(fā)展已經(jīng)成功支持了幾十個對內(nèi)和對外的系統(tǒng)。

問題背景

Monolithic 的問題

Monolith 獨(dú)石就是一塊石頭的意思。正常翻譯一般是“單體”:單體應(yīng)用卷中。這個在前端屆概念不普及矛双,用獨(dú)石這個翻譯更能體現(xiàn)他是什么意思。一整個建筑(或者什么其他東西)是一整塊石頭刻出來的蟆豫。比如石獅子议忽。這就是獨(dú)石的應(yīng)用。這樣做事情在前端工程環(huán)境這個快速變化十减、快速迭代的領(lǐng)域有很多問題栈幸。

上線慢

單體應(yīng)用的一大問題是發(fā)布非常慢。字節(jié)跳動的典型業(yè)務(wù)情況是上一次線需要至少 30 分鐘帮辟,前端的上線就需要這么長的時間速址。當(dāng)然這是我們在 17 年經(jīng)歷的情況,保持我們的發(fā)展態(tài)勢如果不升級技術(shù)由驹,現(xiàn)在可能更慢壳繁。然后 17 年底我們開始了大改版,開始拼命的擁抱微前端荔棉。

原本回滾一次也是 10 分鐘的闹炉。所以當(dāng)時每天上線不了幾次,風(fēng)險(xiǎn)也很大润樱。逐漸導(dǎo)致變更都要憋著渣触,成了“幾天上線一次、一次多個變更”壹若。

我相信這也是絕大多數(shù)聽眾都會有的問題嗅钻。尤其是那種傳統(tǒng)的后臺工程。沒事 webpack 一下你懂的店展。

上下線會很多嗎养篓?很多的,業(yè)務(wù)多了赂蕴,有多少更新都要一起發(fā)布柳弄。

理解困難

當(dāng)然本次是工程化的議題。更需要關(guān)注的影響更大的其實(shí)是框架問題概说。大家都是幾十個項(xiàng)目合作到一個工程里碧注。工程化在搞什么呢其中非常重要一個點(diǎn)就是要“人可以理解”。更低的認(rèn)知成本糖赔,能收獲更低的犯錯概率萍丐。

那這些項(xiàng)目非得維持完全一致的組織模型就基本上是必須的。比如 model 是充血的還是失血的放典?是 contorller 全都放一起逝变、還是根據(jù) router 與視圖們放一起基茵?這些事非常雞毛蒜皮的例子。實(shí)際上深層次的問題與之類似的非常多壳影。

還有其它問題比如 debug 的時候到底能不能找到拱层。也不是單體應(yīng)用不行,單純是說解決這個問題的時候投入了多少精力态贤、多少設(shè)計(jì)舱呻,以及維持這個設(shè)計(jì)規(guī)范問題不崩壞醋火,需要多少精力悠汽。

這一類都是單體應(yīng)用本身的代碼問題〗娌担“拆了就沒這些事了柿冲。”

框架無法調(diào)整

真的從架構(gòu)角度來說兆旬,到底如今的前端項(xiàng)目需要怎么開發(fā)假抄、一般是怎么干的呢。從上一段內(nèi)容讀過來丽猬,我們知道大部分出色的架構(gòu)師工程師都已經(jīng)解決了好多那些困難了宿饱,方式是通過杰出的架構(gòu)設(shè)計(jì)。

然后都知道前端的各種框架各種實(shí)踐實(shí)際上非常多脚祟。前端工程師有個別名不知道你們聽過嗎谬以,叫“npm install 工程師”哈哈,還有“github search 工程師”由桌。

到底發(fā)生了極端困難的情況是來自框架還是來自生產(chǎn)框架的方法呢为黎,這個不好說。但是是個值得琢磨的問題行您。所以你看接手拿到項(xiàng)目什么的別說了你就學(xué)吧铭乾。反正現(xiàn)有架構(gòu)肯定是挺好的。就是你得學(xué)一陣娃循、用對了才好炕檩。

微前端在字節(jié)跳動

這里開始講我們的細(xì)節(jié),分別是服務(wù)發(fā)現(xiàn)捌斧、運(yùn)行隔離捧书、環(huán)境一致以及其他架構(gòu)優(yōu)勢,其實(shí)這幾件事都講完就能發(fā)現(xiàn)在講的主要意思是骤星,具體是什么把一個非常特殊经瓷、對習(xí)慣改變比較大的方案變成可能的。實(shí)現(xiàn)這樣一個與眾不同的方案不是大家聊一聊覺得同意并且開心就能做成洞难。涉及到過程舆吮、成本、風(fēng)險(xiǎn)等方方面面。

“工程師”的任務(wù)不是說證明一個結(jié)構(gòu)在理論上是可以存在的就完了色冀,要有建造這個結(jié)構(gòu)的過程潭袱。比如你拿化學(xué)鍵可以算出來任何可能存在的分子,畫個小人都可以锋恬。但是到底怎么合成屯换,按照什么路徑能讓這種分子被制造,哪種路徑最快最便宜与学,這個是過程的可能性彤悔。通常這才是工程師的任務(wù)。

服務(wù)發(fā)現(xiàn)

服務(wù)發(fā)現(xiàn)的方面我們會首先講一下在整個微服務(wù)模式里他作用是什么索守、有哪些方式晕窑。然后第二部分講到底在解決什么問題,以及多說一些他能提供的新能力卵佛。我們很重視新能力因?yàn)槲覀兊亩ㄎ徊皇窍狸?duì)杨赤,滅了火就完成任務(wù),還有很多新目標(biāo)截汪、很多新好處可以探索實(shí)現(xiàn)疾牲。

最后是講一下在字節(jié)跳動具體是怎么實(shí)現(xiàn)的。

1. 原理

“服務(wù)發(fā)現(xiàn)”就是原來的單體服務(wù)拆分之后衙解,本來一個項(xiàng)目里的方法分開部署了阳柔,誰也找不到誰。需要有個統(tǒng)一的注冊機(jī)構(gòu)丢郊,把提供服務(wù)的各個部署都查到盔沫。

“發(fā)現(xiàn)”就是當(dāng)你想訪問一個微服務(wù),你要怎么找到他枫匾。

這樣就有兩種構(gòu)型架诞,一個是以 Netflix OSS 為典型的,它在客戶端的機(jī)器里先拿到一個服務(wù)目錄干茉,處理邏輯在客戶端的代碼里谴忧。另一種是服務(wù)端的服務(wù)發(fā)現(xiàn),AWS 就是如此角虫。

傳統(tǒng)微服務(wù)的服務(wù)發(fā)現(xiàn)更像是函數(shù)調(diào)用的替代沾谓,拆了之后怎么調(diào)到不同容器里部署的函數(shù)。這里微前端思路非常類似戳鹅,作用略有區(qū)別均驶。微服務(wù)的情況是會區(qū)分像什么訂閱、通知枫虏、請求妇穴、發(fā)布這些爬虱,前端很可能都不用或者表現(xiàn)上不在前端運(yùn)行時使用。還有一些例如“對單”腾它、“對多”這些基本就是前端不太用考慮的東西跑筝。

兩者一致的地方是都誰也不認(rèn)識誰了,如何知道哪些服務(wù)存在瞒滴、誰在提供曲梗?下面就要講一下各種構(gòu)型的服務(wù)發(fā)現(xiàn)和背后的服務(wù)注冊分別具體是什么情況。

客戶端服務(wù)發(fā)現(xiàn) 是說客戶端——也就是服務(wù)的調(diào)用者妓忍,去請求一個注冊的目錄虏两,里面包含所有服務(wù)和負(fù)載均衡的基本信息這些,然后自己決定如何處理单默,使用哪種具體的 load balance 策略碘举。比如 Netflix 的 OSS忘瓦,服務(wù)在 Netflix Eureka 注冊一下搁廓,它心跳給各個客戶端「ぃ客戶端自己搞境蜕,簡單直觀轧粟。

服務(wù)端服務(wù)發(fā)現(xiàn) 是類似 AWS Elastic LoadBalancer 這種叠国。客戶端請求就完了豹芯,服務(wù)端決定怎么給你反向代理罚拟、負(fù)載均衡台诗。

服務(wù)注冊 分自注冊和第三方注冊。自注冊不言而喻赐俗。第三方注冊就是一個崩樱活機(jī)制,定期檢查服務(wù)狀態(tài)阻逮,幫你去管控該上了還是下了粱快。

我們主要用的是第一種:客戶端服務(wù)發(fā)現(xiàn),就是你要多請求一個模塊列表叔扼。這個列表給出的資源是根據(jù)用戶 session 決定的事哭,有豐富的動態(tài)的能力。然后客戶端再根據(jù)這個列表里的各種信息瓜富,去加載模塊資源鳍咱。

2. 給前端帶來了什么?

用服務(wù)發(fā)現(xiàn)的方式去組織微前端与柑,除了使復(fù)雜的上線流程變得解耦谤辜、快捷澎现,還可以使拆散之后的工程版本方便對齊,實(shí)現(xiàn)更高的穩(wěn)定性和可調(diào)試性每辟。還對前端工程帶來好多其他好處剑辫。下面主要講一下各種收益中的最重要的兩個。

快速上線 是什么概念呢渠欺,前面說了幾十個業(yè)務(wù)和在一個項(xiàng)目里妹蔽,一起發(fā)布,這樣發(fā)布的頻率能有多高挠将?實(shí)際考察一下放開限制后的情景胳岂,就會發(fā)現(xiàn)有超乎意料的高。我們的一個微前端應(yīng)用的業(yè)務(wù)是頭條號舔稀,它在 2019 年上半年發(fā)了 2000 個版本乳丰。前面說了傳統(tǒng)上線需要 30 分鐘才能完成打包升級和容器的重啟,并且 10 分鐘才能完一個回滾内贮,這就意味著 1000 小時的上下線等待時間产园。相比之下我們新的方式點(diǎn)一下 HTTP 請求發(fā)出去就生效了,是一個毫秒級的反應(yīng)速度夜郁。

這個擱以前就不是慢什燕、需要干等著的問題了,直接大家就不這樣去發(fā)了竞端。都學(xué) Native 發(fā)版那樣火車式發(fā)布屎即。結(jié)果是響應(yīng)效率降低了很多,很多需求漸漸變得不再由開發(fā)形成瓶頸事富,反而是總要等版本排發(fā)布技俐。

獨(dú)立切換 我們現(xiàn)在就分別發(fā),可以一個單頁應(yīng)用分幾十個模塊统台,各自上各自的雕擂、下各自的。而且后面會說到還可以各自配置自己的 AB 測試版:有 10 個模塊就可以產(chǎn)生 1024 個 AB 版的組合饺谬,20 個模塊 100 萬個捂刺。跟以前完全不敢想象——也就是說一起發(fā)版的時代根本做不了這個事。現(xiàn)在不敢想象的反而是募寨,你說字節(jié)跳動某個業(yè)務(wù)里面不能做 AB 測族展。

我們的頭條號平臺就是剛才一個典型的微前端項(xiàng)目,包含列出的這么多模塊拔鹰,各模塊有獨(dú)立的版本仪缸,和對服務(wù)版本的 session 控制。每個模塊進(jìn)去都是版本列表列肢,有一個模塊所有的歷史版本恰画。通過這個平臺配置小流量宾茂、AB、上線規(guī)則拴还。

運(yùn)行隔離

1. 耦合開發(fā)的嚴(yán)峻形勢

17 年我們推進(jìn)項(xiàng)目的時候有一個很不錯的帖子很流行跨晴,紅遍朋友圈那種,講 react-loadable 的片林。ta 從解耦的維度介紹了這個方向端盆。我們當(dāng)時也有一個很明確的業(yè)務(wù)需求,要把公司不同部門的人組織到一個項(xiàng)目里费封。并且這個項(xiàng)目經(jīng)過經(jīng)年累月的增肥焕妙,已經(jīng)非常臃腫并且積攢了很多值得推敲的、非直接技術(shù)的工程細(xì)節(jié)弓摘。這就意味著要用不同組織焚鹊,不同的技術(shù),不同的工程規(guī)范和打包工具韧献,去合寫同一個平臺末患、同一個工程。如果當(dāng)時用了 iframe 可能就是非常湊合的勉強(qiáng)滿足業(yè)務(wù)势决,完全不符合我們追求極致的習(xí)慣阻塑。

然后當(dāng)時我們很在意一點(diǎn)就是這種跨團(tuán)隊(duì)合作蓝撇,想融合不同的技術(shù)團(tuán)隊(duì)果复,實(shí)現(xiàn)少費(fèi)力溝通或者不重溝通,運(yùn)行隔離是個非常絕對的基本前提渤昌,我們其他分享里面也用了不小的篇幅介紹虽抄,有對內(nèi)的也有對外的。當(dāng)時的效果是什么呢独柑。這個是我們 18 年 4 月內(nèi)部培訓(xùn)錄制到的當(dāng)時情況:

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

我們把線上的頁面(左圖)通過調(diào)試工具插入腳本迈窟,臨時移除掉沙盒功能,得到的右圖效果忌栅。

2. 運(yùn)行隔離的目標(biāo)

運(yùn)行隔離是啥意思车酣,回想一下剛才說的 AB 測的問題,20 個項(xiàng)目是多少個組合索绪。如果把這個對應(yīng)到 bug 的維度湖员,大家都在一個應(yīng)用里亂跑會有多恐怖。那么這樣的組合對我們的程序和程序員提出了什么樣的要求瑞驱?

不跑掛 說是“對一切工程師最基本要求”娘摔,我覺得不算夸張。所有軟件工程師的第一個能力層級都應(yīng)該是不把系統(tǒng)拖垮唤反。微服務(wù)之后這個問題不明顯了凳寺,因?yàn)橛屑軜?gòu)層面的方式解決了絕大多數(shù)挑戰(zhàn)鸭津。我很信服的一個理論是所有程序員都是四個階段:寫完需求,不拖垮別人肠缨,能擴(kuò)容逆趋,性能好。

不干擾 也是另一個大問題晒奕,我們當(dāng)時西瓜團(tuán)隊(duì)和頭條是兩個獨(dú)立的 App父泳,他們和我們的合作完全跨部門,連 polyfill 的規(guī)則都不一樣吴汪。事先也是做了很多公共組件惠窄、 CSS 約定之類的。但是規(guī)范和約定遠(yuǎn)遠(yuǎn)不夠漾橙。協(xié)作的境界從最差到最好應(yīng)該是:

  • 定規(guī)范:誰來了都好好學(xué)杆融、好好聽,自己對自己的行為負(fù)全責(zé)霜运。
  • 能 enforce 規(guī)范:不憑自覺脾歇,而是用工具和流程等手段去發(fā)現(xiàn)和強(qiáng)制,實(shí)現(xiàn)可靠性淘捡。
  • 不需要規(guī)范:系統(tǒng)的確定性由系統(tǒng)解決藕各。靠人去發(fā)現(xiàn)和執(zhí)行規(guī)范是消耗大量認(rèn)知資源的焦除,帶來的都是額外的工作量和系統(tǒng)的不確定性激况。

3. 沙盒

我們還有另外一篇文章專門介紹沙盒的設(shè)計(jì)和采坑經(jīng)驗(yàn)。這篇就快速用幾張圖示意一下膘魄。

① 變量保護(hù): 全局變量乌逐、 DOM 和 CSS 基本都是走的這條路。前后兩次快照创葡,我們來比較浙踢,之后根據(jù)需要幫你恢復(fù)現(xiàn)場。這塊內(nèi)容不細(xì)說了灿渴,看一眼圖就不言而喻:一次比較對照所有 key洛波、兩次遍歷、黑名單 location骚露、白名單 readonly蹬挤。估計(jì)我這樣一說大家都懂。

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

② 沙盒時序: 稍微多說一些荸百。右圖是我們做的 ABCDE 五個模塊的加載和混行的時序圖闻伶。虛線左邊是加載,右邊是獨(dú)占線程所占用的時間够话。也就是說有 ABCDE 五個模塊五個沙盒蓝翰,分別在這個模塊編譯(下載光绕、創(chuàng)建 js 變量和函數(shù)、運(yùn)行這些語句畜份、最終生成一個 React Component)和運(yùn)行時(這個模塊被打開诞帐、渲染對應(yīng)的所有功能)。

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

這里面兩個基礎(chǔ):js 單線程爆雹、事件循環(huán)

我們用了非常單純的單進(jìn)程操作系統(tǒng)的思路停蕉,比喻一下就是 js 的單線程就像單核 CPU 一樣。你激活一個模塊钙态,相當(dāng)于激活一個線程慧起,其他都退到背景里。

實(shí)際上單核單進(jìn)程不是必然册倒,大家都知道這個原理蚓挤。在事件循環(huán)的基礎(chǔ)上,我們可以封裝所有的異步操作驻子,把回調(diào)套在沙盒激活后面灿意。比如 setTimeoutaddEventListener,這樣每個模塊看起來就像是在并行崇呵。這塊可以說的很多缤剧,但是就想一下操作系統(tǒng)的比喻就好了。

4. 加載方式

React 的項(xiàng)目用 react-loadable 本身不多說了域慷,VUEraw (也就是不包含展示層框架的原始版)的各種項(xiàng)目荒辕,我們都提供 masterpage 的樣例,每個版本對應(yīng)的都實(shí)現(xiàn)了一套和 react-loadable 相似的效果芒粹。

子模塊(Modules) 就是一個個的 CMD 包兄纺,我用 new Function 來包起來。其他就是具體主工程(MasterPage)項(xiàng)目框架的約定化漆,load 過程分為 5 個鉤子:

  • preload 是否預(yù)加載,是個 promise钦奋,fullfill 的時候就會觸發(fā) Ajax座云。各種空閑政策阻塞政策都可以由 master 制定;
  • loadCondition 編譯前置條件付材,fullfill 了才會開始運(yùn)行這部分朦拖,執(zhí)行結(jié)果就是得到那個 CMD 的 exports
  • provider 是一個模塊的入口的函數(shù)厌衔,由模塊開發(fā)者提供璧帝,返回模塊的一切輸出。這個函數(shù)的傳入?yún)?shù)由 masterpage 主工程來提供富寿。
  • loaded 完成加載睬隶,得到編譯結(jié)果了锣夹。
  • 等等后面不說太細(xì)了。

環(huán)境一致

因?yàn)槲覀冎岸际窃谥v微服務(wù)是什么和落地效果如何苏潜,從來沒有講過 推行一個微服務(wù)你得做什么∫迹現(xiàn)在這部分內(nèi)容是我們第一次公開分享的,也是一個很獨(dú)立的維度恤左。

其實(shí)就是在講為什么對微前端來說這個環(huán)境一致工具是必須的贴唇,是繞不過的必經(jīng)之路。如果不搞也很容易就栽進(jìn)坑里飞袋,項(xiàng)目失敗戳气。然后很可能還不知道是為何失敗的,把問題歸結(jié)為框架不好啊巧鸭、人不好啊甚至微前端就不好啊之類的問題上物咳。

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

1. Serverless vs container

container 就是一個寄生環(huán)境,盡管這個環(huán)境還是挺特殊的蹄皱,不像 linux 這種完整操作系統(tǒng)览闰。相比之下 Serverless 就特殊多了。特殊到連谷歌云都曾經(jīng)在商業(yè)上被擊敗巷折。

這里舉兩個 Serverless 的例子压鉴,比如 lambda。它的本地工具是一個 CLI 系統(tǒng):SAM锻拘,是一個非常典型的必要基礎(chǔ)設(shè)施油吭。如果說發(fā)展容器化 AWS 全是靠 docker,發(fā)展 lambda 就是靠的 SAM署拟。

另一個典型的例子 firebase婉宰。想必前端的同學(xué)們都非常清楚,也都用過他們的開發(fā)套件推穷。這些工具都非常重視一點(diǎn)就是本地開發(fā)心包,我做個項(xiàng)目到底能不能先測試再上÷澹或者說先調(diào)試在上蟹腾。

要做的話就是盡可能模擬真實(shí)環(huán)境了,SAM 的話就模擬了 API Gateway区宇,memory limit 這些娃殖。有 live debugging、 local debugging议谷。不然的話發(fā)什么瘋有人敢把線上業(yè)務(wù)放到一個非常不同的環(huán)境下運(yùn)行炉爆。

2. 你是不是環(huán)境有問題(在我這是好的)

標(biāo)題程序員最常說的一句話對不對,另一種表達(dá)是“我這是好的”。大家都知道絕大多數(shù)情況這么說話不對芬首,但常常會忍不住說赴捞。甚至更像是其實(shí)是對自己說。一種捫心自問衩辟,自我拷問螟炫,“我這是好的啊”。

我們用沙盒把微前端做成了像 container艺晴,像瀏覽器里的 docker昼钻。但是不夠,我們還是把寄生在 masterpage 內(nèi)這種應(yīng)用框架的特征封寞,也就是業(yè)務(wù)具體邏輯然评,看成是一種 Serverless。

然后我們還把隔離的思路做到極致狈究,我們的 dev 命令是通過啟動參數(shù)啟動一個完全獨(dú)立的 Chrome 會話碗淌,有自己的 cookie 啊緩存啊這些,效果像是裝了 2 個 Chrome 乃至多個 Chrome抖锥。然后代理工具默認(rèn)也配到了啟動參數(shù)亿眠,是個 pac 文件。所以也可以單獨(dú)用或者裝 switchy 用磅废。

代理工具 就是調(diào)試環(huán)境的整個配置纳像,那些走測試環(huán)境、哪些走線上請求全部代理管理拯勉。生成一個動態(tài)的 pac 地址和代理服務(wù)竟趾。就是剛才說的。

關(guān)鍵請求宫峦,比如服務(wù)發(fā)現(xiàn)的請求岔帽,顯然是代理掉的。走一個我們?yōu)楸镜丨h(huán)境定制的返回值导绷。更細(xì)節(jié)的功能是我們可以協(xié)助調(diào)試主工程(MasterPage)犀勒、 組合上某個 module,你也可以用指定的 MasterPage 版本來調(diào)用你正在編寫的模塊诵次。

你也可以指定是否加載完整的線上模塊列表账蓉、只替換你正在調(diào)試的模塊。

我們也還有完整的植入 webpack dev server 的服務(wù)供選擇逾一。前面說了支持任意打包工具,這塊是解耦的肮雨,只不過你用了我們可以幫你 reload遵堵,部分刷新動態(tài)刷新。后面再細(xì)說。

發(fā)布檢查 是針對服務(wù)注冊這一塊陌宿。這塊的一部分锡足,我們的 build 命令有一套檢查,對應(yīng) git 鉤子壳坪。

方便調(diào)試 我們還在一定程度上支持了 HMR舶得。我們可以像開發(fā)一個普通前端應(yīng)用一樣開發(fā)主工程(MasterPage)和子模塊(Module),子模塊更新后改變模塊管理器狀態(tài)爽蝴,并由內(nèi)置的 eventbus 機(jī)制來重新渲染 HMR沐批,這個機(jī)制也可以用到盛傳環(huán)境。

我們的公共庫可以通過在 MasterPage 項(xiàng)目里引入蝎亚、子模塊里 external 的方式實(shí)現(xiàn)模塊間共享九孩。也支持子模塊使用特定版本的基礎(chǔ)庫。

Vue 用到了全局變量及原型鏈擴(kuò)展发框,暫時還不支持 Hot Reload 的調(diào)試躺彬。

其他的框架優(yōu)勢

框架上看就是 serverless 的方向。不是真的 serverless 是前端 serverless梅惯,業(yè)務(wù) module 開發(fā)者很多東西都不用再關(guān)心了宪拥。舉個例子就是 console.log。現(xiàn)在大家都知道線上業(yè)務(wù)要干干凈凈體體面面铣减,把 console 都收拾整齊她君。這是我們之前提到的規(guī)范的層面,我們可以做到吸收所有 console徙歼,存儲錯誤堆棧犁河。然后用戶反饋的時候作為 trace 元數(shù)據(jù)提交到反饋后臺等等。

這些都是 masterpage 層面的框架了魄梯。當(dāng)然不是必然關(guān)系桨螺。但是可以說微前端給了一個非常方便像這樣組織項(xiàng)目的渠道。

我們線上的 sourcemap 也是根據(jù)服務(wù)發(fā)現(xiàn)的管理后臺權(quán)限控制的酿秸,只有開發(fā)者能看灭翔。

下一代前端展望

前面講了,服務(wù)發(fā)現(xiàn)是一個對前端可用資源的總體管理辣苏。這個能力是不局限于運(yùn)行時的微服務(wù)前端的肝箱。對一切資源都適用,下面說一下這塊稀蟋。

服務(wù)發(fā)現(xiàn) + CDN

抽象一個完整的前端訪問煌张,首先拆成 3 步:A 頁面加載,B“服務(wù)發(fā)現(xiàn)”退客,C 根據(jù)服務(wù)發(fā)現(xiàn)結(jié)果加載資源骏融。那就有不同的變種链嘀。最直觀的就是 AB 結(jié)合,SSR 畫上去档玻,把 html 請求下來怀泊,module list 資源列表已經(jīng)全了。這個系統(tǒng)我們這代號 GOOFY误趴。當(dāng)然也可以 ABC 都組裝進(jìn)去霹琼。這個后面細(xì)說。

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

另外一個思路就是 BC 結(jié)合凉当,我請求一個列表枣申,不用說我可以把 js 內(nèi)容都 combo 進(jìn)去。少一些額外的請求纤怒。

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

總之大意就是這個 ABC糯而。

Token 解析

前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用

中心服務(wù)從中心機(jī)房把規(guī)則心跳給邊緣節(jié)點(diǎn),邊緣節(jié)點(diǎn)接收客戶請求泊窘,就近解析出基本的 token熄驼,這個過程中不依賴其他服務(wù)。

這個 token 由同樣在邊緣的頁面服務(wù)提供烘豹。因?yàn)槊撾x了到中心機(jī)房驗(yàn)證的步驟所以 token 時效有一定依賴前端 SDK瓜贾。

高可用

高可用可以說是邊緣計(jì)算的一個極大的好處,額外給了我們一個收益携悯。這套系統(tǒng)的容災(zāi)基本等同于智能 DNS 對應(yīng)的探針奔缆活這一套成熟技術(shù)了。

我們需要的就是把邊緣節(jié)點(diǎn)心跳到一個監(jiān)控服務(wù)上憔鬼,他們會分鐘級動態(tài)修改 DNS龟劲。如果沒有足夠的邊緣節(jié)點(diǎn)生存,還可以 DNS 到傳統(tǒng)的中心機(jī)房轴或。

這樣絕大多數(shù)流量都不需要進(jìn)出中心機(jī)房昌跌,資源都是就近的、多播的照雁。

結(jié)尾

以上就是本次分享的全部內(nèi)容蚕愤,我們從落地的細(xì)節(jié)分享了字節(jié)跳動兩年來使用微前端的經(jīng)驗(yàn),以及面對這些挑戰(zhàn)時的思考過程饺蚊。非常幸運(yùn)我們的項(xiàng)目有足夠多給力的伙伴們支持萍诱,最終獲得了比較大的成功,也非常明顯地提升了重量級的產(chǎn)品的質(zhì)量污呼。

微前端和很多前沿和剛剛發(fā)展的概念一樣裕坊,本身還在快速的演進(jìn)和驗(yàn)證的過程中,我們的具體實(shí)踐也一直在快速的變化燕酷,在不斷地發(fā)現(xiàn)弱點(diǎn)和糾正它們碍庵,也在努力發(fā)展更多的可能映企。在這個從種種不完美到更完美的奮斗過程中悟狱,能給讀者分享我們的成果是我們的一種榮幸静浴。而且在分享后,如果能收到指教挤渐、討論和建議我們會更加感激苹享,并且非常歡迎。也歡迎更多的有識之士加入我們浴麻,具體可參見 job.bytedance.com

原文標(biāo)題:前端微服務(wù)在字節(jié)跳動的打磨與應(yīng)用
原文鏈接:https://mp.weixin.qq.com/s/iLdAH9p2-S8pFyZrNzYaNg

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末得问,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子软免,更是在濱河造成了極大的恐慌宫纬,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膏萧,死亡現(xiàn)場離奇詭異漓骚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)榛泛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝌蹂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人曹锨,你說我怎么就攤上這事孤个。” “怎么了沛简?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵齐鲤,是天一觀的道長。 經(jīng)常有香客問我椒楣,道長给郊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任撒顿,我火速辦了婚禮丑罪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凤壁。我一直安慰自己吩屹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布拧抖。 她就那樣靜靜地躺著煤搜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唧席。 梳的紋絲不亂的頭發(fā)上擦盾,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天嘲驾,我揣著相機(jī)與錄音,去河邊找鬼迹卢。 笑死辽故,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腐碱。 我是一名探鬼主播誊垢,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼症见!你這毒婦竟也來了喂走?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谋作,失蹤者是張志新(化名)和其女友劉穎芋肠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遵蚜,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帖池,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谬晕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碘裕。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖攒钳,靈堂內(nèi)的尸體忽然破棺而出帮孔,到底是詐尸還是另有隱情,我是刑警寧澤不撑,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布文兢,位于F島的核電站,受9級特大地震影響焕檬,放射性物質(zhì)發(fā)生泄漏姆坚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一实愚、第九天 我趴在偏房一處隱蔽的房頂上張望兼呵。 院中可真熱鬧,春花似錦腊敲、人聲如沸击喂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懂昂。三九已至,卻和暖如春没宾,著一層夾襖步出監(jiān)牢的瞬間凌彬,已是汗流浹背沸柔。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铲敛,地道東北人褐澎。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像原探,于是被迫代替她去往敵國和親乱凿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容