1688 複雜業務場景下的 Serverless 提效實踐

Serverless發表於2022-03-14

1688 複雜業務場景下的 Serverless 提效實踐

作者 | 遠巖(阿里巴巴 CBU 技術部 Serverless & 工程效能負責人)

前言

首先為大家簡單介紹一下我們的業務場景,1688 隸屬於阿里集團的國內貿易事業部(CBU),是阿里最早起家的業務,已有十幾年的歷史。我們主要負責 PC 端 1688.com 以及手機端阿里巴巴 APP,是目前國內最大的 B 類電商交易平臺,主要面向 B2B 電商業務的場景,為中小企業提供零售、批發、分銷以及加工定製等電商交易渠道。

我本人是在 1688 團隊的無線服務端技術團隊,團隊主要是給 App 端提供業務支援,負責 1688 手機端 App 內部的各種場景構建,比如首頁推薦、商品詳情等等,也是典型的電商業務場景。
image.png

FaaS 在 1688 的演進之路

image.png
1688 對 FaaS (Function as a Serverles) 技術的探索要追溯到 2015 年左右。當時整個阿里集團最大的業務目標就是“ALL IN 無線”,移動網際網路剛剛興起,需要快速地把存在 PC 端的業務,無論是淘寶也好,還是 1688,需要能迅速地把它移植到移動端上面去,生成 App 來搶佔移動端流量。

在這樣一個大的業務背景下,1688 的解決方法是設立無線服務端。通過微服務體系呼叫 PC 端存量的業務介面,然後面向前臺的移動端業務去進行一些輕量的業務邏輯編排和 UI 層的對映,最後通過移動閘道器,就可以快速為APP 端提供擁有同樣業務能力的服務介面。

移動網際網路端的功能迭代非常之快,在這種模式下,我們很快遇到了問題:傳統的微服務體系構建、發揮、部署和除錯時間都非常漫長,而面向前臺的業務改動又非常頻繁,速度要求很快。技術能力和業務訴求之間產生的錯位,push 著我們去尋找和探索更好的解決方案。

FaaS 能力落地的兩個階段

FaaS 在 CBU 內部的落地經歷了兩個大階段。第一個階段是 2015 年,部門內部自研了一套基於 JVM 的動態載入系統,來實現快速釋出、快速上線、熱部署等等,基本實現了FaaS的效果。第二階段則是從去年開始,我們與阿里雲 FC 團隊進行共建,將整個 FaaS 能力的底座更換為阿里雲的函式計算,以獲得更好的彈性伸縮、容器隔離等能力。

MBOX:基於 JVM 動態載入能力的 FaaS 系統

前文說到,在整個無線端業務快速迭代的背景下,我們需要一種能夠實現快速釋出變更服務端介面的能力。在 2015 年左右,Java 工程界主流的思路是充分利用 JVM 的動態載入特性:即在不重啟 JVM 的前提下,通過一定的機制將外部的程式碼實時編譯成 class 位元組碼,然後動態地載入正在執行的 JVM 例項中,從而實現熱載入的效果。

於是,基於上述的思路,我們打造了一套基於 JVM 的動態服務載入系統 —— MBOX。在 MBOX 中,我們構建了一個通用的輕量服務容器,該容器可以接收來自外部的一段程式碼(可能是一個 Java 類 或者是一個簡單的 groovy 指令碼),並對程式碼進行實時的編譯,生成 class 位元組碼。之後容器本身還會對生成的位元組碼進行一定的安全加固操作(如消除死迴圈等),最後通過一個自定義 class loader 把它載入成線上正在執行的 JVM 中的一個 class,生成物件例項、注入中介軟體代理,便可以對外提供服務。

image.png

基於 MBOX,我們實現了線上編碼、線上預覽和秒級釋出的能力,以現在的視角來看,它就是一個非常典型的 FaaS 服務平臺,並具備以下特點:

一、相比於傳統微服務,它是線上開發的模式,隨寫隨用,所見及所得,研發效率非常高。

二、熱載入更新機制。它可以做到秒級的釋出,整個業務上線的迭代效率十分高。

三、對於使用平臺的開發者來講,它帶來了 Serverless 的體驗,因為所有的運維、機器部署等等,全部是由 MBOX 平臺來承擔,開發只需要關心其業務邏輯的實現即可。(在這裡,我們扮演了類似現在雲服務廠商的角色)

在長達五年的時間裡,MBOX 系統承載了整個 1688 超過 10 萬 QPS 的業務呼叫,巔峰時期有超過 1500 個線上函式,節省了大量人力資源,在整個無線業務擴張階段立下了汗馬功勞,也為我們的 Serverless 技術探索之路開啟了一扇大門。

說完了優點,我們再談一談這套系統的缺點和風險:

首先,第一點是隔離性問題,因為是 MBOX 基於 JVM 的, JVM 本身沒有辦法提供有效的資源隔離機制(如CPU、記憶體等),所以存在比較大的安全風險:即同一個業務容器中載入的多個服務之間會彼此產生影響。比如今天這個業務叢集 A 上面有一個人寫的程式碼發生了記憶體洩露,結果可能是整個叢集的效能都被拖慢,上面所有的服務都會受到影響,這是一個非常嚴重的安全隱患。

第二點是程式碼的開發模式太輕,純指令碼式開發,只能寫個程式碼片段,雖然開發起來很快很爽,但是沒有工程結構,不能使用框架、不能使用任何的設計模式,這樣導致可應用場景非常受限,程式碼本身的質量也很差。

第三點對於 MBOX 的維護方來說,資源的管理是一個非常頭疼的問題,經常遇到整個叢集水位飆升,但是又沒有辦法判斷出來到底是哪一個服務在裡面佔用了資源的情況。而系統本身又無法很好的進行彈性伸縮,只能依賴人肉手動擴容,到了平臺維護的後期,運維成本是非常高的。

到了 2019 年左右,MBOX 的一些問題已經比較凸顯了,而這時業界在 K8S 的影響之下,掀起了 Serverless 和雲原生的技術浪潮,我們立刻開始了對應的技術調研,最終在 2020 年底與阿里雲函式計算團隊展開共建,希望能夠打造一套真正面向雲原生的 FaaS 平臺。

阿里雲 FC:基於 Serverless + Sidecar 的 FaaS 系統

阿里雲函式計算(FC)在 K8S 容器自動運維能力的基礎上,打造出了一套高彈性、強隔離,且易於開放定製的 FaaS 基建,目前已經基本成為整個阿里集團內部 FaaS 能力的統一解決方案。

image.png

除了底層高度成熟和強大的彈性自動運維能力之外,FC 還提供了開放度非常高的 Runtime 設計,任何語言甚至是任何團隊都可以定製自己的執行時框架,從而最大限度滿足業務一線開發人員的訴求。

對於跨語言的老大難問題 —— 中介軟體呼叫上,FC 團隊和中介軟體團隊,結合微軟最新開源的 DAPR 技術,實現了一套標準化的 Sidecar 能力,涵蓋了 RPC、快取、訊息佇列、配置中心等常見中介軟體,抹平多語言差異的同時進一步精簡了使用者的執行時容器,讓函式的冷啟動和彈性速度得以進一步提升。

最終在 FC 底層強大技術的支撐下,我們一同共建了面向集團內 Java 研發者通用的 Runtime 框架及研發運維配套設施,替換了原有的 JVM MBOX 系統,實現了 FaaS 能力的技術換代。

image.png

回顧 CBU 的 Serverless 演進之路,從最早的微服務架構,到自主研發的 JVM FaaS 系統,再到現在的 FC 函式計算,逐步探索出了最適合業務場景的技術方案,同時也算是在業界率先邁出了大規模落地 FaaS 的一步:作為集團第一批大規模落地 Serverless 理念的部門,我們的 FaaS 系統在部門內擁有超過 80% 的業務滲透率,使用時間更是達到了 5 年以上。

FaaS 落地的靈魂三問

在瞭解了 FaaS 的能力和實現之後,我們接下來討論大家最關心的問題:如何在業務系統中落地 FaaS 能力?

以我們過往的實踐經驗,在實際業務中落地 FaaS 並非大部分人想象中那麼“絲滑”,勢必會遇到一些問題,這裡提煉了三個我們認為最核心的“靈魂拷問”:

一是存量業務的改造。對於存量的業務(尤其是我們這種已經持續執行了很多年的業務),有大量的歷史包袱不能拋掉。這就面臨一個問題,線上大量的傳統 Serverful App,怎麼去轉換成 Serverless Function?直接進行改造風險是非常大的,是否有辦法在保障現有業務穩定執行的前提下,以最小的成本獲得 FaaS 帶來的優勢?

二是 FaaS的碎片化問題。傳統 Serverful 應用的構建思路是非常高內聚的,某個業務的核心能力基本都聚合在幾個微服務應用中,數量相對較少。但是函式不同,它輕量化的特點會導致數量膨脹非常快,如果不加以設計和控制,那麼很容易出現一個業務背後對應著幾十個函式的碎片化情景出現。

三是研發提效的問題。業界目前普遍認為 Serverless 能夠大幅提升研發效率,但是真正落地之後會發現研發提效這件事情,並沒有那麼簡單,只是將傳統的 Serverful 應用換成 Serverless 函式能夠帶來的研發提效幅度是非常有限的。

image.png

一、存量的複雜業務如何與 FaaS 結合?

首先回答第一個問題,在存量複雜業務和 FaaS 能力結合這件事上,通過實踐探索,我們總結出了兩種比較落地的模式,分別是 BFF 模式和擴充套件點模式。

BFF模式

BFF 模式是現在 FaaS 落地比較常見的一種主流做法。我們可以把傳統 Serverful App 裡面的邏輯進行一些抽象,一般來說在我們可以根據變更的頻繁度,將業務場景中的邏輯分為兩層:一部分的程式碼邏輯比較輕,同時沒有一些複雜的依賴,但是產品的需求可能大部分集中在這部分,稱其為 變動層。另一部分的程式碼可能是業務的應用框架,中介軟體二方依賴,以及一些核心的重業務邏輯,相對來說改動不會太多,但是改造風險非常大,改造收益也可能不盡理想,稱其為 穩定層。

如果你的業務應用可以按照上述的思路拆分,那就非常適合採用 BFF 模式,把變動層抽象出來,放到 Serverless 函式中去,這樣就實現了一個類似 BFF 層的效果,前臺的消費方其實是直接通過函式再去消費 Serverful App 裡面穩定層的 API。這樣就可以構造一個業務的緩衝區,能夠實現更快地釋出 & 交付以及更少的運維。雖然有相當一部分的老程式碼包袱還是丟不掉的,但是可以集中 80% 的精力提效。

這種模式比較適用於前臺類的業務場景,比如說傳統應用 M-V-C 架構當中的 controller 層,就非常適合使用 FaaS 來替換。

image.png

擴充套件點模式

第二種模式是擴充套件點模式,擴充套件點模式比較適合於偏中後臺的場景,或者說業務裡面的一些中臺系統,例如我們的商品中心,就用到了這個模式。
image.png
對於中後臺類的應用,一般本身就十分複雜,且業務邏輯非常多,加上歷史比較悠久,不適合進行大刀闊斧地改造。但是我們可以把複雜的業務邏輯層進行一定的抽象,面向未來設計一些關鍵的擴充套件點,同時提供擴充套件點的 FaaS 適配方案。這樣對於一些後續增量的業務邏輯,就可以使用FaaS的能力來提供,而對於存量的業務邏輯,則可以基本保持不變,只需要在程式碼結構上稍作適配,也可以成為標準的擴充套件點實現。

擴充套件點模式的另一個好處是可以讓原來封閉式的架構變得更加開放化,採用這種模式後,即便是中臺性質的應用,只要制定好擴充套件點的對接規範,任何的業務方都可以通過提供自定義的 FaaS 函式來實現自己想要的擴充套件能力。在 1688 的商品中臺系統中,就通過這種擴充套件點模式實現了商品價格計算邏輯的業務開放化定製能力。

二、避免 FaaS 的碎片化問題

程式設計介面的權衡

早期我們在 MBOX 系統中定義函式的程式設計介面時,採用的是指令碼式程式設計,使用者的程式設計粒度就是一段程式碼,一個Java類。這種方式雖然寫起來非常輕量,但是會導致函式數量非常多(為了實現一個稍複雜的業務,可能需要寫很多個指令碼),同時由於沒有工程結構,程式碼質量非常低下,也無法使用一些設計模式)。因此在基於FC制定函式的程式設計介面時,我們基於上述經驗設定了一個規則,那就是使用者函式的執行粒度應該是一個“Micro App”,而不是“Single Function”;程式設計介面的粒度應該是一個“Code Project”,而不是“Single Script”。

基於這樣的原則,對於開發者來說,一個函式例項更接近於一個微應用,整體保留了最精簡的工程結構,即可以以較低的成本進行單一功能點的實現,同時也可以進行復雜邏輯的開發,引入各種二、三方庫,不至於產生非常嚴重的函式數量膨脹和碎片化問題。

建設內部服務市場

儘管採用了 Micro App 式的函式粒度定義,在業務中使用到的函式數量仍然會比傳統微服務應用多出好幾個量級,為了解決這個問題,我們設計了【業務域 】-【函式組】- 【函式】- 【介面】四層緯度的函式分類定義,並在函式的工程模板裡埋入了外掛,在函式完成構建釋出的時候自動採集上報這些分組分類資訊,最終建設出面向內部研發人員的函式服務市場,讓大家能夠直觀的看到當前所存在的函式分類,以及各個介面API的歸屬資訊。
image.png

三、研發效率的瓶頸在哪裡?

讓開發者能夠 “Only focus on business”,這是Serverless從誕生之初就標榜的核心理念,但是如果只是簡單將運維等底層基礎設定切換到Serverless的基建之上,引入 FaaS 等相關技術能力,其實對研發人員而言離真正意義上的“Only focus on business”還差很遠。

在我們初期落地 Serverless 時,確實發現研發同學編寫程式碼的效率好像高了很多,但是從整體的業務團隊的業務需求交付角度來講,研發效能沒有發生質變的提升:大部分的需求研發流程仍然比較冗長,需求推進過程中的溝通成本、協作成本依然巨高不下。仔細審視我們會發現,研發效能的關鍵瓶頸很多時候可能並不在於“研發”本身,而在於程式碼之外。

那麼Serverless能夠為研發提效是否是一個偽命題呢?當然也不是,首先,Serverless和FaaS確實可以大幅度降低運維和編碼的成本,提升效率;其次,Serverless技術的出現讓服務端的技術門檻降低,使得一些非服務端專業的研發人員也能夠有能力開發一些簡單的業務邏輯,這使得需求的全棧式開發成為可能。從整體需求交付的效率來考量,假設研發人員能夠獨立完成整個需求的所有開發工作,無需和他人進行聯調溝通,那麼效率勢必是最大化的 —— Serverless 為這種全新研發模式的落地和普及帶來了可能性,或許才是“Only Focus on Business”真正的意義所在。

總之,Serverless 也並不是提效的銀彈,事實上,沒有任何一門技術是銀彈,當我們期望研發效能提升的時候,更多的還要從全域性的視角來進行審視,而不是將思路僅僅聚焦在“研發”階段。

複雜業務場景的提效實踐

最後我們以一個實際的業務場景為例子,給大家介紹一下 1688 在存量複雜業務場景下,是如何結合 FaaS 能力進行研發提效的。

這裡先簡單介紹一下 1688 的商品詳情業務場景:商品詳情就是商品面向買家的最終展示頁面,承載了大量的商品資訊。1688 的商品詳情頁和其他普通C類電商不一樣的地方在於:面向 B 類的交易會存在多種交易渠道,例如現貨批發 、分銷鋪貨、加工定製等等,其中每個渠道的交易方式、價格、庫存邏輯都不一樣;初次之外B類電商對於消費品、工業品等不同行業的商品,在表達上也會存在巨大差異;不同渠道和行業定製,再疊加各類電商營銷活動玩法,使得1688的商品詳情頁面業務複雜度非常之高。
image.png

原本的技術架構中涉及到了多個團隊,其中包括底層的商品基礎團隊(對接集團中臺商品的能力,沉澱領域模型的服務和一些核心的商品邏輯)、無線服務端團隊(將底層商品基礎服務面向客戶端和前端封裝成專用的商品詳情介面)、搭建投放團隊(負責為頁面提供一定的搭建、投放橫向能力支援)以及最終展現側的ios、安卓、前端三端。

除此之外,在面對一些業務定製類的需求(如分銷等)時,還需要對應的業務團隊參與,這種模式下,一個需求最多會有 5、6 個團隊在同時協作,溝通成本非常高;再加上服務端側採用了比較重的微服務應用模式,研發和運維效率都比較低下。

前臺業務邏輯收攏:BFF 模式

我們首先是在業務核心變化最多最快的前臺業務邏輯層,以BFF模式引入了FaaS能力,並且將所有的UI相關邏輯都上行收攏到了FaaS函式中。這樣做一方面提升了服務端對應邏輯的研發和部署效率,另一方面使得前端和客戶端的元件只需處理最簡單的展示邏輯,從而儘可能抹平多端技術差異,讓一些跨端能力得以實現。

商品後端:擴充套件點模式支援定義

商品後端側面對的主要問題是各種定製業務邏輯的接入成本過高,因此我們採用了FaaS擴充套件點模式來進行優化:將商品資訊的核心邏輯(如價格、庫存)抽象成一個個標準的擴充套件點,並對接函式閘道器,允許任意的業務方按照模板編寫一個函式來定製其業務邏輯,從而實現封閉架構的開放化。

image.png

經過上述的技術架構改造後,我們可以看到整個需求研發的模式和鏈路發生了非常大的改變。在之前老的模式下,如果要定製一個業務的商品詳情,需要從業務後端到客戶端多個團隊全部參與,非常多的鏈路都需要進行改動,成本是非常高的。而在新的模式下,從核心業務邏輯的定製,到前臺展現側的業務邏輯實現,都可以通過編寫簡單的FaaS函式來實現,甚至完全可以僅由一位同學完成所有後臺業務邏輯的變更。(如果前端和客戶端的元件能夠實現低程式碼+跨端開發,那麼完全可以實現業務需求的全棧開發!)

image.png
最後我們來看一下整體業務場景完成改造後所帶來的成效,在結合了FaaS的研發模式下,商品詳情相關的需求發待時長降低了 80%、釋出頻次提升 300% +,需求的吞吐量也有提升;最關鍵的是,研發人員的投入減少了50%,整個後端側由原來的2個正式員工人力投入降低為僅需半個正式員工+1個外包員工支援,參與需求開發的相關團隊和人員減少了許多,整個研發交付鏈路變得十分簡潔明瞭。

總結與展望

最後還是站在當下的時間節點,以業務團隊的視角,簡單的對Serverless技術做一個總結和展望。

以我們過往業務場景落地的經驗總結幾個關鍵結論:

  1. Serverless 無疑是一輪新的技術革命,FaaS 等核心技術所帶來的生產力提升已經在很多場景得到有力的證明。
  2. Serverless 的落地要結合實際的業務場景有的放矢,而不是說一杆捅到底。
  3. 任何技術都不是提效“銀彈”,研發效能的提升更多還要是站在團隊的組織架構和人的角度去思考來做業務和技術的結合。

而對於Serverless和FaaS後續的發展,我也在此作出一些比較個人的看法,歡迎大家理性討論:

  1. FaaS將會持續進化:雖然目前 Serverless 的 FaaS 能力已經比較成熟,但是仍有很大進步空間。可以擁有更好的彈效能力以及冷啟動速度。我們可以看到業界正在WASM、eBPF等新的方向上不斷的探索,有理由相信接下來我們將在這個領域看到持續的突破。
  2. FaaS不會完全替代傳統微服務:傳統微服務(包括執行在K8S上的)與 FaaS 這兩種形態,至少在未來很長一段時間裡仍然會共存,業務團隊應該做好這種準備,因地制宜地在業務場景中結合兩種技術,發揮它們的優勢。
  3. 全棧和低程式碼(或者說,低門檻)研發將會成為一種趨勢:我們看到,Serverless的興起給研發提效帶來了一種全新的思路,全棧式的業務需求開發能夠大幅降低專案中的溝通和協作成本、提升需求的吞吐量。隨著Serverless技術的進一步成熟和推廣,這將可能改寫現在研發團隊的形態。

相關文章