什麼是 BFF
BFF 全稱是 Backends For Frontends (服務于前端的後端),起源于 2015 年 Sam Newman 一篇部落格文章
《Pattern: Backends For Frontends —— Single-purpose Edge Services for UIs and external parties》。
微服務和前後端分離的流行,在後端服務邊界上通常會有一個 API 層,向下調系統内的多個微服務,經過聚合、适配和裁剪等一些列的處理後,向上為前端提供 HTTP 協定的 API。

然後随着移動端的興起,出現了 H5、iOS 和 Android 等多端并存的開發場景,由于移動端的螢幕尺寸比較小,是以顯示的資訊和傳統 Web 端會有較大的差別,而且移動端對于通路連接配接數和資料量也有更高的要求。此時通用 API 層的開發就會碰到一些困境,比如需要為不同的端提供不同的 API。而這些 API 的設計與不同端上的展示邏輯相關性較強,是以不太适合由後端團隊或者 API 團隊來負責。因為這些 API 的維護人員會夾在前後端之間去做協調和取舍,非常的心累。
Sam Newman 先後在 REA 和 SoundCloud 兩家公司實踐了為不同的端做獨立的 Backend API,稱之為 BFF。以解決不同端對 API 的差異化需求的問題。
BFF 的好處
曆史遺留業務支撐
一些老系統的接口規範可能比較陳舊,比如說不是 Restful 的。借助于 BFF 層做一些接口轉換,更好的适配端上技術發展的需求。
協調穩定的中台和多變的端需求
端上變化快主要展現在兩個方面:
- 技術革新:端上的技術更新比較快,js 架構層次不窮。移動端也有很多選擇,有 H5、Java/OC、Kotlin/Swift、React Native、Flutter等等。
- 業務變化:前端的産品變化往往會比後端的業務變化更頻繁。
補齊端側的差異化投放能力
有些産品在投放到不同的國家、語種、人群中時,可以在 BFF 層做一些轉換,比如後端的報錯可以在這裡做一些和使用者語種相關的翻譯。
橫向聚合和基于聚合的優化
有一些産品子產品會涉及到多個中台服務,BFF 可以作為邊緣服務層,起到聚合 API 的作用。
端上的業務效能評估
在端上嘗試一種新的體驗難免要改變 API。如果沒有 BFF,為了 A/B 測試需要同時修改前端和 API。假如移動和 Web 團隊都需要跑 A/B 測試怎麼辦?一個團隊可能需要等待另一團隊。
BFF 讓不同團隊可以獨立的進行試驗。您可能會發現,首先在 BFF 中實施實驗性 API 更改,然後将試驗移植到 A/B 測試中,然後再将其移植到核心 API 中,更為友善。
BFF 的一些問題
資源成本高
不管 BFF 多簡單,都需要提供一台伺服器運作,嚴格一點的話,還需要提供幾套環境部署。比如一些大公司内部
要求,不管多麼簡單應用都需要 4 台伺服器,并且伺服器的審批流程可能會比較慢長。
并發性難以保障
BFF 層一般由前端的同學開發,然而保證 BFF 高可用,對前端的同學往往是個挑戰。當通路量突增時,可能出現 BFF 這層先被打爆,導緻整個系統架構可用性被拉低。
運維困難
誰開發誰運維,然後前端的同學可能缺乏運維線上應用經驗,BFF 的運維也是個很大的問題。
Serverless For Backend
由于 Serverless 特别是
函數計算,在應用部署之後,假如沒有通路量就不會消耗計算資源,更不會産生費用。當通路量增加以後,平台會以百毫秒級别的速度對應用進行擴容,通路量下降以後背後的計算資源(函數執行個體)也會随之收縮。同時也給使用者提供了開箱即用監控報警和日志檢索功能。
函數計算彈性伸縮、按量付費和免運維的優勢正好是對應了傳統 BFF 的缺點。是以将 BFF 部署到函數計算平台就可以非常完美的解決上述 BFF 的問題。
當部署成本下降以後,也為 BFF 拆解得更小提供了可能性。此時端側可以按照業務子產品來組織對應的 BFF 子產品。比如說,營運平台的前端開發自己負責對應的 BFF 子產品開發,裝置中心的前端負責自己的 BFF,互相之間可以少一些沖突,真正做到誰享受誰負責。
基于函數計算的方案
函數計算平台的 BFF 架構方案有四層:端側、網關層、BFF 層和中台服務。
端側可以保持自己熟悉的技術方案進行開發。比如網頁端可以選擇 React 或者 Vue.js,移動端可以選擇 Java/Kotlin 或者 Objective C/Swift。也可以選擇 React Native 或者 Flutter 這種跨多端的方案。
網關層有兩種選擇:API Gateway 和 HTTP Trigger。API Gateway 的功能豐富,支援限流,但是會産生額外的費用。HTTP Trigger 支援簡單的路由映射,綁定域名,雖然不支援限流但是免費的,适用于輕量級應用。
BFF 層建議按照業務子產品進行拆分,不同的功能子產品建不同的函數,如果不同端的子產品之間的接口差異較大也可以拆解成不同的函數。然後通過 Fun 工具把這些函數組織成若幹個項目。項目的拆解可以考慮按照維護的團隊進行拆分,不同的團隊維護不同項目,減少之間的交叉和沖突。
SFF 研發流程
下面我們從本地開發、釋出流程和服務監控三個方面看看 SFF 的研發流程怎麼弄。
本地研發
本地工程分為三個部分
- APP/H5 - React Native 或者 Vue.js 等端側技術
- SFF - FC 函數,常見的有 express 或者 egg
- 中台 API 接口 - 可以選擇 API Mock 或者直連測試環境。
本地調試。偏好指令行的開發者可以使用
funcraft工具通過 fun local start 本地啟動服務。偏好桌面 GUI 的開發者可以使用函數計算提供的
VSCode Plugin單元測試可以選中自己喜歡的測試架構:Mocha 或者 Jest
下面是一種建議的項目結構
sffdemo
├── README.md
├── function
│ ├── package.json
│ ├── template.yml
│ └── user.js
├── package.json
└── src
├── component
├── layout
├── model
├── page
└── service
src 目錄放置 APP 或者 H5 的代碼。function 目錄放置 bff 代碼,可以用 ROS 模闆 template.yml 描述函數,使用 fun 工具進行釋出。
釋出流程
日常開發建議使用指令行釋出,安裝和配置 fun 工具以後,在 BFF 項目中放置一個 template.yml 的 ROS 描述檔案,然後借助于 fun deploy 指令進行快速部署。
新手也可以選擇去
函數計算控制台,使用 ZIP 檔案包上傳的方式釋出。
對于更複雜的場景可以配置 CI/CD。比如說代碼倉庫選擇 Gitlab/Github,建構系統選擇 Travis CI/Gitlab CI/Jenkins ,送出代碼到代碼倉庫自動觸發建構和釋出。更多細節可以參考
Serverless 實戰 —— Funcraft + OSS + ROS 進行 CI/CD服務監控
關于可觀察性方面,函數計算提供了開箱即用的監控、日志和報警。
成本優勢
使用者的應用負載通常具備多種類型,對資源的規格和彈性要求各不相同。函數計算提供了預付費和後付費計量模式,幫助您在不同場景下獲得顯著的成本優勢。預付費是指使用者先判斷應用的資源需求,預先購買指定數量的資源消費券後再使用。預付費的優點是單價低,比後付費便宜 70% 左右;缺點是應用負載動态變化,按照峰值購買資源将導緻較低的資源使用率。後付費是指使用者根據應用實際使用的資源按需付費。函數計算按量資源是根據執行個體執行請求的時間付費,精确到百毫秒。如果沒有請求,則無需付費。是以可以認為按量資源的使用率是 100%。後付費的優點是資源使用率高,缺點是單價高。函數計算的自動伸縮能夠讓您将預付費和後付費資源無縫結合起來,在不同場景下都能獲得有競争力的成本。
更具體的費用計算和成本優化方案可以參考
函數計算成本優化最佳實踐小結
每個人對 Serverless 的定義和落地都可能有不一樣的了解。借助于函數計算帶來的 Serverless 優勢,BFF 真正的做到了誰享受誰負責、低成本和免運維。