飛豬基于 Serverless 的云+端實(shí)踐與思考
過去兩年,飛豬前端一直在積極地進(jìn)行 Serverless 建設(shè)和實(shí)踐,2019 年 - 2020 年我們和集團(tuán) Node 架構(gòu)組、研發(fā)平臺(tái)一起完成了基礎(chǔ)能力的建設(shè)和業(yè)務(wù)試點(diǎn),成為集團(tuán)率先落地 Serverless 實(shí)踐的 BU,2020 年 - 2021 年我們開始大規(guī)模地在飛豬推廣使用 Serverless 的能力,從導(dǎo)購全鏈路到核心中后臺(tái),都能夠看到 Serverless 的身影,這一年我們完成了 Serverless 從業(yè)務(wù)試點(diǎn)到生產(chǎn)力工具的轉(zhuǎn)變,本文將主要分享飛豬基于 Serverless 的實(shí)踐成果以及未來想要做的事情。
Serverless 的使用規(guī)模
2020 年 - 2021 年飛豬 Serverless 的規(guī)模和重要度都有很大的變化,主要表現(xiàn)在三方面:
- 一是函數(shù)組規(guī)模增長(zhǎng)一倍以上,Qps 峰值增長(zhǎng) 650%。
- 二是使用 FaaS 開發(fā)的人員規(guī)模增長(zhǎng) 560%,其中前端人員 80% 以上參與到 FaaS 的開發(fā)中。
- 三是影響力的表現(xiàn),目前不僅飛豬前端都對(duì) Serverless 很熟悉,客戶端也有很多人參與到 FaaS 的開發(fā),更重要的是后端和產(chǎn)品同學(xué)也知道我們有 Serverless 進(jìn)行服務(wù)開發(fā)的能力。
具體的數(shù)據(jù)如下:
為什么要引入 Serverless
飛豬為什么這么迫切地要引入 Serverless?這主要是出于前后端研發(fā)模式升級(jí)以及前端職能擴(kuò)展的考慮,下面回顧一下飛豬前端架構(gòu)的發(fā)展和研發(fā)模式的演進(jìn)。
1. 飛豬前端架構(gòu)的發(fā)展
飛豬前端架構(gòu)總結(jié)下來就是從最初純粹的前端開發(fā),到解決多端一致性的跨端開發(fā),再到接管視圖服務(wù)端邏輯的前臺(tái)開發(fā),Serverless 就是前端升級(jí)轉(zhuǎn)變的核心一環(huán)。
2. 研發(fā)模式的演進(jìn)歷程
前端人員為什么一定要參與服務(wù)側(cè)開發(fā)?從前后端研發(fā)模式的演進(jìn)來看,主要經(jīng)歷了以下三個(gè)大的階段:
- 第一階段是資源解耦,這個(gè)階段前端把靜態(tài)資源分離出來部署到 cdn,解決了和后端服務(wù)同機(jī)部署的耦合。
- 第二階段是模板解耦,我們之前提到的前后端解耦大部分指的就是模板的解耦,一種不徹底的解法就是渲染解耦,服務(wù)端放一個(gè)空模板內(nèi)容部分全靠 CSR,徹底的解法就是前端接管模板,可以獨(dú)立部署模板也可以使用 node.js 替代。
- 第三個(gè)階段就是試圖解耦,一方面是由于客戶端體系和前端的離線體系的限制,端側(cè)對(duì)于視圖的動(dòng)態(tài)性要求極高,沒有服務(wù)側(cè)能力的前端只能將視圖的動(dòng)態(tài)性放在服務(wù)端做,另一方面由于端側(cè)架構(gòu)對(duì)于數(shù)據(jù)接口協(xié)議的特殊要求,需要服務(wù)端來進(jìn)行協(xié)議的轉(zhuǎn)換,也就是服務(wù)端常說的 Do 到 Vo 的處理,這就造成了前后端視圖的耦合,為了去除這部分耦合,前端通過 Node.js 做 BFF 層來接管視圖層的邏輯,Serverless 則是給了前端做 BFF 開發(fā)的最佳選擇。
3. 為什么一定是 Serverless
其實(shí)在 Serverless 出現(xiàn)之前,前端也嘗試了用 node 應(yīng)用來做 BFF 層的開發(fā),飛豬也是在 2017 年通過 Midway + React SSR 的架構(gòu)將飛豬 PC 主鏈路首頁、搜索、商品詳情、訂單詳情 Node 化,但是應(yīng)用級(jí)別的開發(fā)在前端存在以下幾個(gè)問題:
- - 開發(fā)成本高:Node 應(yīng)用級(jí)別的開發(fā)對(duì)于新手前端還是具備一定的開發(fā)成本,之前做過粗略的估計(jì),上手成本至少需要 3 人/日,還不包括后續(xù)的性能優(yōu)化、內(nèi)存泄漏排查等一系列能力。
- 運(yùn)維成本高:Docker、鏡像、機(jī)器日志查看、域名申請(qǐng)、機(jī)器替換等一系列運(yùn)維能力對(duì)于前端來說具備非常高的復(fù)雜度,也是注定無法推廣的一個(gè)重要原因。
- 機(jī)器成本高:前端在使用應(yīng)用開發(fā)時(shí)過度偏向于前端架構(gòu)設(shè)計(jì)帶來的應(yīng)用離散和機(jī)器利用率低的問題,根本原因是前端在用頁面開發(fā)的思維去做應(yīng)用開發(fā),導(dǎo)致新建一堆應(yīng)用占用大量閑置機(jī)器。
2017 - 2019 年也是集團(tuán) Node 開發(fā)停滯的兩年,這個(gè)階段由于上述問題的閑置,Node 開發(fā)無法在移動(dòng)端鋪開,前端使用 Node 主要在中后臺(tái)的開發(fā),這時(shí)矛盾主要表現(xiàn)在前端迫切渴望研發(fā)模式轉(zhuǎn)變和涉足服務(wù)端開發(fā)的高昂成本,直到 Serverless 浪潮的出現(xiàn)讓我們看到了曙光,下面來看下 Serverless 能給前端帶來什么樣的變化:
Node FaaS 通過將中間件集成到 Runtime 的上下文中,開發(fā)通過 Api 的方式調(diào)用來實(shí)現(xiàn)極低上手和開發(fā)成本,只要會(huì)寫 js 就能在 0.5 人/日內(nèi)上手 FaaS 開發(fā),同時(shí) Serverless 容器底層通過機(jī)器統(tǒng)一管理、鏡像統(tǒng)一、靈活調(diào)度、按需付費(fèi)等方式向開發(fā)者屏蔽容器的運(yùn)維,兩者結(jié)合完美地幫我們解決了之前 Node 應(yīng)用開發(fā)遇到的三大問題,至此前后端研發(fā)模式升級(jí)的最后一塊拼圖集齊,前端開始云+端的變革。
飛豬云+端的核心落地場(chǎng)景
1. 落地場(chǎng)景總覽
從飛豬首頁到搜索、頻道,再到大促會(huì)場(chǎng),Serverless FaaS 實(shí)現(xiàn)了在飛豬導(dǎo)購全鏈路的覆蓋,成為飛豬前端的常用生產(chǎn)力工具之一。另外中后臺(tái)開發(fā)已全面使用 FaaS 開發(fā),并且賦能客戶端同學(xué),下圖右側(cè)的包體積平臺(tái)就是飛豬客戶端同學(xué)使用 Node FaaS 開發(fā)完成。
2. 云+端場(chǎng)景 - 數(shù)據(jù)協(xié)議處理
數(shù)據(jù)協(xié)議處理是 BFF 層最為常見的場(chǎng)景,包括接口合并、Do 到 Vo 的轉(zhuǎn)換等,飛豬 80% 以上的 C 端 FaaS 場(chǎng)景都是用作數(shù)據(jù)協(xié)議的處理,通過 FaaS 來做協(xié)議轉(zhuǎn)換能夠解放服務(wù)端,同時(shí)增強(qiáng)前端對(duì)視圖層的控制,可謂一舉兩得。
一個(gè)最新的例子(如下圖所示),這是一個(gè)飛豬的內(nèi)容詳情頁,頁面涉及內(nèi)容中臺(tái)、評(píng)價(jià)中臺(tái)、互動(dòng)、算法等 5 個(gè)以上接口,這些接口都是現(xiàn)成的分散在各個(gè)系統(tǒng),對(duì)于前端來說肯定是不想在端上調(diào) 5 次接口,不管是從性能還是架構(gòu)設(shè)計(jì)上考慮,都是不合理的,這時(shí)就需要一個(gè)服務(wù)端接口的合并,F(xiàn)aaS 就非常適合做這樣的事情,通過原子能力的拼裝,無需服務(wù)端介入,極大縮短了需求的交付周期。
3. 云+端場(chǎng)景 - SSR 同構(gòu)渲染
SSR 同構(gòu)渲染并不是一個(gè)新的概念,最早在 React 支持 SSR 的時(shí)候,前端就具備一套代碼在 Server 和 Client 端執(zhí)行的能力,飛豬這邊早在 2017 年就在 pc 端上線了 Midway + React SSR 的頁面。
移動(dòng)端由于流量比 PC 大很多,且在 Server 側(cè)執(zhí)行 Js 是一個(gè)極耗機(jī)器資源的操作,通過 Node 應(yīng)用的方式做 SSR 機(jī)器和運(yùn)維成本跟隨著頁面流量指數(shù)級(jí)上升,ROI 并不高,但是 Serverless FaaS 的自動(dòng)托管,能幫前端解決機(jī)器利用率和運(yùn)維成本的問題。
再配合客戶端的文檔預(yù)加載,我們可以做到客戶端預(yù)加載直出率(500ms下)100%,端外渲染 2s 達(dá)標(biāo)率 90+%,性能提升 80% 以上。
4. 云+端場(chǎng)景 - 一體化應(yīng)用
一體化研發(fā)是一種更加符合前端人員習(xí)慣的開發(fā)模式,常見的分為中后臺(tái)一體化和 Rax+FaaS 一體化,將 FaaS 代碼和 Assets 代碼在一個(gè)倉庫下開發(fā),調(diào)試和部署能夠極大地提高開發(fā)效率,目前飛豬用得最多的就是中后臺(tái)一體化開發(fā)。
Serverless 研發(fā)配套建設(shè)
在基礎(chǔ)建設(shè)方面定義為兩部分:研發(fā)態(tài)效率的提升和運(yùn)行時(shí)穩(wěn)定性的保障。
1. 研發(fā)態(tài)效率
開發(fā)階段主要涉及的操作是新建項(xiàng)目、調(diào)試和發(fā)布,飛豬通過已有的 Clam 工程體系集成 FaaS 的腳手架模板,對(duì)接 def api 打通創(chuàng)建項(xiàng)目、迭代和發(fā)布的能力,讓前端同學(xué)開發(fā) FaaS 能有和開發(fā)頁面一樣的體驗(yàn),降低上手和開發(fā)成本,同時(shí)封裝 Mtop 調(diào)用和容災(zāi) SDK,封裝常用 FaaS Utils 集合的方式提高代碼的復(fù)用度。
2. 運(yùn)行時(shí)穩(wěn)定性
通過函數(shù)監(jiān)控 Alinode、網(wǎng)關(guān)監(jiān)控 Sunfire 以及全鏈路日志的排查能力,做到問題的快速發(fā)現(xiàn)和定位。
通過 tair 容災(zāi)和 cdn 容災(zāi),保障大部分場(chǎng)景在函數(shù)或者網(wǎng)關(guān)掛掉的情況下,仍能夠正常展示頁面。
未來
2020 年 - 2021 年我們完成了 Serverless 向生產(chǎn)力工具的轉(zhuǎn)變,2021 年 - 2022 年總體來看是徹底完成飛豬研發(fā)模式轉(zhuǎn)變的目標(biāo),讓 FaaS 成為前后端都習(xí)以為常的一環(huán),規(guī)劃還沒做具體,有以下幾個(gè)關(guān)鍵的事情要做:
- - 中后臺(tái)和長(zhǎng)尾函數(shù) 0 - 1 的彈起嘗試:這塊考慮到一些中后臺(tái)函數(shù)和長(zhǎng)尾函數(shù)每天可能只有幾十個(gè) Uv 夠不到 Qps 級(jí)別,目前預(yù)留 1 核機(jī)器的方式仍是有些浪費(fèi),考慮在不影響初次請(qǐng)求的情況下嘗試 0 到 1 的彈起,做到機(jī)器的極致利用率。
- 飛豬物理網(wǎng)關(guān)的替換:目前雖然飛豬 Java 的網(wǎng)關(guān)出于維護(hù)狀態(tài)投入較低,但是一旦流量發(fā)生變化,網(wǎng)關(guān)的穩(wěn)定性會(huì)成為瓶頸,希望能夠有 Fc 專門的團(tuán)隊(duì)接管流量網(wǎng)關(guān),之前飛豬也是完成了一個(gè)線上試點(diǎn),2021 年 - 2022 年繼續(xù)推進(jìn)。
- 研發(fā)態(tài)和運(yùn)行時(shí)問題的可觀測(cè)增強(qiáng):從 FC 底層容器到函數(shù)代碼內(nèi)部再到函數(shù)依賴、流量網(wǎng)關(guān),不管是部署出現(xiàn)的問題還是線上的問題,都比較難定位,通常需要拉著 FC、研發(fā)平臺(tái)、Runtime 的同學(xué)一塊排查,后續(xù)希望能推動(dòng)可觀測(cè)性的增強(qiáng),讓業(yè)務(wù)開發(fā)能夠快速發(fā)現(xiàn)問題。
寫在最后
基于 Serverless 的云+端結(jié)合已經(jīng)基本成型,這將是前端近些年來最大的變革之一,未來 FaaS 將是前端開發(fā)不可或缺的一環(huán),我們需要用它來做研發(fā)模式升級(jí),也需要用它幫助前端擴(kuò)大職能,通過 FaaS 的能力讓前端開發(fā)深入到服務(wù)層,更好地貼近業(yè)務(wù)、理解業(yè)務(wù)、幫助業(yè)務(wù)。
作者簡(jiǎn)介
王恒飛(承蔭),飛豬旅行前端技術(shù)專家,飛豬 Serverless 引進(jìn)和實(shí)踐者,探索和推動(dòng)云+端的研發(fā)模式。