天天看點

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

作者:阿裡雲技術

簡介:我們主要負責 PC 端 1688.com 以及手機端阿裡巴巴 APP,是目前國内最大的 B 類電商交易平台,主要面向 B2B 電商業務的場景,為中小企業提供零售、批發、分銷以及加工定制等電商交易管道。

前言

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

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

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

(電商業務場景)

Serverless 落地選型

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

(FaaS 在 1688 複雜業務場景下的提效實踐)

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 能力的底座更換為阿裡雲的函數計算,以獲得更好的彈性伸縮、容器隔離等能力。

(1) MBOX:基于 JVM 動态加載能力的 FaaS 系統

前文說到,在整個無線端業務快速疊代的背景下,我們需要一種能夠實作快速釋出變更服務端接口的能力。在 2015 年左右,Java 工程界主流的思路是充分利用 JVM 的動态加載特性:即在不重新開機 JVM 的前提下,通過一定的機制将外部的代碼實時編譯成 class 位元組碼,然後動态地載入正在運作的 JVM 執行個體中,進而實作熱加載的效果。

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

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

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

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

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

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

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

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

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

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

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

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

(2) 阿裡雲 FC:基于 Serverless + Sidecar 的 FaaS 系統

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

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

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

對于跨語言的老大難問題 —— 中間件調用上,FC 團隊和中間件團隊,結合微軟最新開源的 DAPR 技術,實作了一套标準化的 Sidecar 能力,涵蓋了 RPC、緩存、消息隊列、配置中心等常見中間件,抹平多語言差異的同時進一步精簡了使用者的運作時容器,讓函數的冷啟動和彈性速度得以進一步提升。

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

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

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

FaaS 落地的靈魂三問

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

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

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

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

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

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

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

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

(1) BFF 模式

BFF 模式是現在 FaaS 落地比較常見的一種主流做法。我們可以把傳統 Serverful App 裡面的邏輯進行一些抽象,一般來說在我們可以根據變更的頻繁度,将業務場景中的邏輯分為兩層:一部分的代碼邏輯比較輕,同時沒有一些複雜的依賴,但是産品的需求可能大部分集中在這部分,稱其為變動層。

另一部分的代碼可能是業務的應用架構,中間件二方依賴,以及一些核心的重業務邏輯,相對來說改動不會太多,但是改造風險非常大,改造收益也可能不盡理想,稱其為穩定層。

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

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

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

(2) 擴充點模式

第二種模式是擴充點模式,擴充點模式比較适合于偏中背景的場景,或者說業務裡面的一些中台系統,例如我們的商品中心,就用到了這個模式。

對于中背景類的應用,一般本身就十分複雜,且業務邏輯非常多,加上曆史比較悠久,不适合進行大刀闊斧地改造。但是我們可以把複雜的業務邏輯層進行一定的抽象,面向未來設計一些關鍵的擴充點,同時提供擴充點的 FaaS 适配方案。

這樣對于一些後續增量的業務邏輯,就可以使用 FaaS 的能力來提供,而對于存量的業務邏輯,則可以基本保持不變,隻需要在代碼結構上稍作适配,也可以成為标準的擴充點實作。

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

避免 FaaS 的碎片化問題

(1) 程式設計界面的權衡

早期我們在 MBOX 系統中定義函數的程式設計界面時,采用的是腳本式程式設計,使用者的程式設計粒度就是一段代碼,一個 Java 類。這種方式雖然寫起來非常輕量,但是會導緻函數數量非常多 (為了實作一個稍複雜的業務,可能需要寫很多個腳本,同時由于沒有工程結構,代碼品質非常低下,也無法使用一些設計模式)。

是以在基于 FC 制定函數的程式設計界面時,我們基于上述經驗設定了一個規則,那就是使用者函數的運作粒度應該是一個 “Micro App”,而不是 “Single Function”;程式設計界面的粒度應該是一個 “Code Project”,而不是 “Single Script”。

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

(2) 建設内部服務市場

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

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

研發效率的瓶頸在哪裡?

讓開發者能夠 “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 的商品詳情頁面業務複雜度非常之高。

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

原本的技術架構中涉及到了多個團隊:

  • 其中包括底層的商品基礎團隊 :對接集團中台商品的能力,沉澱領域模型的服務和一些核心的商品邏輯;
  • 無線服務端團隊 :将底層商品基礎服務,面向用戶端和前端封裝成 — 專用的商品詳情接口;
  • 搭建投放團隊 :負責為頁面提供一定的搭建、投放橫向能力支援,以及最終展現側的 ios、安卓、前端三端。
  • 除此之外,在面對一些業務定制類的需求 (如分銷等) 時,還需要對應的業務團隊參與。

這種模式下,一個需求最多會有 5、6 個團隊在同時協作,溝通成本非常高;再加上服務端側采用了比較重的微服務應用模式,研發和運維效率都比較低下。

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

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

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

商品後端側面對的主要問題是各種定制業務邏輯的接入成本過高,是以我們采用了 FaaS 擴充點模式來進行優化:将商品資訊的核心邏輯 (如價格、庫存) 抽象成一個個标準的擴充點,并對接函數網關,允許任意的業務方按照模闆編寫一個函數來定制其業務邏輯,進而實作封閉架構的開放化。

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

經過上述的技術架構改造後,我們可以看到整個需求研發的模式和鍊路發生了非常大的改變。在之前老的模式下,如果要定制一個業務的商品詳情,需要從業務後端到用戶端多個團隊全部參與,非常多的鍊路都需要進行改動,成本是非常高的。

而在新的模式下,從核心業務邏輯的定制,到前台展現側的業務邏輯實作,都可以通過編寫簡單的 FaaS 函數來實作,甚至完全可以僅由一位同學完成所有背景業務邏輯的變更。(如果前端和用戶端的元件能夠實作低代碼 + 跨端開發,那麼完全可以實作業務需求的全棧開發!)

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

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

總結與展望

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

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

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

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

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

本文為阿裡雲原創内容,未經允許不得轉載。

繼續閱讀