转-BFF调研-1
轉自:??https://blog.csdn.net/duola8789/article/details/89332064?
?
前端開發中存在的難問題
問題:服務端設計的接口究竟是面向UI,還是面向通用服務?
BFF
解決方案: Backends For Frontends, 簡稱BFF。
BFF最適合的場景,為第三方提供定制API等差異化場景,每個用戶體驗(客戶端)對應一個后端,
BFF作為用戶體驗適配層,對后端接口進行組合、處理,對數據進行:裁剪、格式化、聚合、編排。
BFF理念中,最重要的一點是:服務自治,誰使用誰開發,所以一般由前端維護。
BFF實現不限制具體技術,可以自由選型:Java/Node/PHP/Python,但大部分前端團隊都會選擇Node.js。
BFF的演化歷程
BFF和網關(API Gateway)是微服務架構中兩個重要概念,可以通過下面的例子講解BFF的出現過程
服務化架構V1
實現單塊應用的解構拆分,微服務初步完成,前端用戶體驗層主要是傳統的服務端Web應用,服務化架構如下所示:
服務化架構V2
隨著無線應用的流行,除了Web應用外,服務還需要為新的無線原生App來提供接口和數據,先采用下面的服務架構:
這樣的架構的問題是:
服務化架構V2.1
為了解決這個問題,在用戶體驗層和內部微服務層之間引入了BFF層,將后端的微服務進行適配,想用戶體驗層暴露有號和統一的API,方便無線設備接入訪問后端服務
這種架構解決了上面的問題:
但是隨著接入設備的增加,也會有一些問題:
微服務架構V3
為了解決這個問題,引入API Gateway
在這種架構下:
- 路由,將來自無線設備的請求路由到后端的某個微服務BFF集群
- 認證,對涉及敏感數據的API訪問進行集中認證鑒權
- 監控,對API調用進行性能監控
- 限流熔斷,網關能夠進行限流熔斷,保護后端服務
- 安全防爬,收集訪問日志,通過后臺分析惡意行為,阻斷惡意請求
微服務架構V4
可以對V3架構進行優化,將傳統的服務端Web應用模式改為前后分離架構,前端采用H5單頁技術提供給用戶更好體驗。
同時增加了下手是哪個第三方應用開放API的能力
拓展新的接入渠道,形成了一個完成的現代微服務架構,從外到內依次為:端用戶體驗層->網關層->BFF層->微服務層
具體實現
細分力度
要求把一個大后端拆分為多個小后端,有三種方式
- 用戶體驗級(UI)
- 端級
- 團隊級
一般建議按照用戶體驗級來拆分
對接下游服務(微服務)
(1)如何對接多個技術棧不同的下游服務
RPC協議調用
(2)如何管理、組合調用
借助RXJava、Finagle等事件機制來簡化這些異步流程控制
(3)某個調用失敗時,如何保障可用性
在BFF層容錯,同時前端保證可接受不完整相應內容
復用問題
拆分后,多個BFF間會產生冗余代碼,這是不可避免的。
可以添加API網關層,將通用的后端邏輯(授權、認證、限流)放進去
想消除冗余,又不想因為抽離可復用代碼而導致BFF間緊耦合,所以就有了一種折衷的態度:容忍BFF間冗余、消除單BFF內冗余。也就是允許一定程度的BFF間冗余
螞蟻財富的BFF實踐
2016年時,湯堯對BFF在螞蟻財富項目中的落地實踐進行了介紹。
在引入BFF之前,螞蟻財富的業務也遇到了上面提到的問題,主要是體驗層API經常變化,導致開發效率低下。
于是引入了BFF,主要的目的是對數據進行:裁剪、格式化、聚合、編排。
一個理想的模型如下:
在實際落地過程中,形成了如下的架構:
他們在實戰過程中,主要解決了一下幾個問題:
(1)Node.js與Java通信
- 數據:跨語言序列化協議hessian
- 服務:Node弱類型,Java強類型,如何調用
這個調用過程一般是通過RPC協議完成的,而非通過HTTP協議。
由于我對Java沒有接觸,而且資料只是他當時的PPT,沒有詳細的講解,沒有辦法理解具體是如何實現的。而且恐怕對于大多數前端開發工程師來說,與Java的通信也是BFF落地過程中一個比較嚴峻的挑戰,而且這是在前端開發人員有比較好的Node開發能力的基礎上。
(2)多App適配
在API網關層處理多個App的通用的邏輯,比如錯誤碼管理、數據一致性、免登、業務日志等。
(3)聚合
- 傳給客戶端需要的數據,簡化客戶端邏輯,減少網絡開銷
- 避免無意義的透傳
- 敏感信息過濾
(4)接口設計準則
基礎服務接口:(微服務?)
- 細粒度
- 通用的功能,可能會被多個BFF用到
- 提供含各種狀態的mock真實數據,易于同步開發(如何實現?)
BFF API設計
- 合理設計接口數量,太多不易維護
- 提供含各種狀態的mock真實數據,頁面不依賴server開發(如何實現?)
- 多協議發布(如何實現?)
- 規范數據格式
在落地BFF過程中,從技術角度來看:
- 前端和BFF由同一人完成
- 前端需要具備服務端技能
- 快速的應用發布能力(docker?)
TWA的理念與實踐
在2018年的SEE Conf,螞蟻金服的不四(知乎ID:死馬)對在BFF基礎上發展出來的TWA(Techless Web Application)開發體系進行了介紹(視頻和PPT)。
傳統的分層:
BFF負責聚合底層業務數據,給客戶端提供接口,秉承誰使用誰維護的理念,一般由前端團隊維護。
業務實際上分為三層:前端(HTML/CSS/JS)+ BFF(Node.js接口聚合層)+ 后端服務(Java)
BFF on Chari是螞蟻自研的,基于Egg.js的BFF框架,打通了Node到Java的RPC通信鏈路
Egg.js已經開源(Egg.js是以Koa作為基礎框架),需要基于Egg.js去打造屬于自己的BFF框架
RPC的意思是不在一個內存空間的兩個應用,借助網絡來實現,像調用本地的函數一樣去調用遠程函數
BFF不是銀彈,有著自己的問題:
- 研發成本上升:前端團隊既要開發客戶端,又要開發BFF,人手不夠
- 流程繁瑣:BFF引入后,要同時走前端、服務端的研發流程,多端發布、互相依賴,導致流程繁瑣
- 運維經驗不足:主要是前端工程師運維經驗不足(給業務團隊帶來了很大困擾)
盡管職責劃分越來越清晰,但是由于前后端發布系統不一致,前端團隊仍需要在基于不同的代碼倉庫進行研發,走不同的發布流程
理想的開發流程:
螞蟻金服推出的解決方案TWA(Techless Web Application),是一個全棧的研發框架
TWA是為了提升開發者研發體驗而推出的漸進式解決方案,開發者在一個代碼倉庫下,基于TWA的框架,完成客戶端和BFF層的研發,通過Basement研發平臺提供的流程支持,不用再關注應用、構建、部署、流程等細節,可以一鍵將應用部署到各個運行終端,同時在研發平臺上完成應用的自主運維和監控
將TWA拆解開來,分為了三個大的方向:框架、研發平臺、運行時
- 框架:提供了前后端合一的框架,通過定制化網關,抹平多個終端和接入形式的差異,讓一套代碼可以運行在不同的終端下(?)
- 研發平臺:Basement,提供TWA的研發迭代、自主運維和監控,精簡規范了H5 APP的研發流程
- 運行時:通過基礎服務和Docker,給客戶端代碼和服務端代碼提供穩定可靠的運行環境
框架
是一個漸進式框架,可以選擇部分能力使用
客戶端、服務端目錄、依賴都是相互獨立的。
復雜的終端環境,有不同的接入鏈路(可能通過網關走TCP長連接通信)、不同的鑒權方案。如果每個業務的BFF系統要對接到每個系統完成接入、鑒權是非常復雜的。
解決方案是:TWA網關層 + 客戶端RPC Client,
TWA網關層統一完成所有終端的接入、鑒權,BFF不需要對接到每個終端,只需要對接到網關,讓BFF接口統一
客戶端的RPC Clinet是一個請求庫,對接到網關,將客戶端的鑒權、接入的細節隱藏,并且可以自動選擇接入鏈路
這就可以在client目錄下,像調用本地方法一樣,調用server中目錄下的服務
研發平臺
Basement,一站式運維平臺,基于Docker,支撐整個應用的研發流程,完成自動化的測試和部署
Node與Java的通信
與使用的微服務框架有關,可以采用HTTP的方式,也可以通過RPC調用。
螞蟻金服的實踐
- 數據:跨語言序列化協議hessian
- 服務:Node PRC
開源框架:
有贊的實踐 – HTTP
可以采用服務注冊中心:
首先,Java應用服務啟動的時候,會往服務注冊中心注冊服務,這里的服務注冊中心可能是ETCD或者Zookeeper,然后,Node應用在啟動的時候,會先從服務注冊中心拉取服務列表,接著Node會跟Java服務建立一條TCP長鏈接,除此之外,Node還需要負責Hession協議解析以及負載均衡等。
上面的方式Node職責比較重,對Node開發的要求高,有贊在此基礎上做了改進:
在Node和Java之間添加了一層中間代理層Tether,Tether是用Go語言寫的一個本地代理,Tether會對外暴露一個HTTP的服務,對Node來說,只需要通過HTTP方式調用本地的服務即可,其他服務化相關的服務發現、協議解析、負載均衡、長鏈建立維護都交由Tether來處理。這樣,Node這一層就非常輕量了,Node是調用Java服務時:
const Service = require('../base/BaseService');class GoodsService extends Service {/*** 根據商品 alias 獲取商品詳情* @param {String} alias 商品 alias*/async getGoodsDetailByAlias(alias) {const result = this.invoke('com.youzan.ic.service.GoodsService','getGoodsDetailByAlias',[alias]);return result;} } module.exports = GoodsService;- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
這種方式的優點:
總結
關于TWA
TWA是螞蟻金服自研的,整合了BFF的一整套漸進式的前端+Node聚合層的開發體系,它不僅包括了BFF的引入,還包括了前后端代碼管理、部署、運維等功能框架。
但是很遺憾的是,TWA沒有開源,對于想要從0開始引入BFF,想實現TWA的功能,還有一個努力的過程。
實際上我們引入BFF,不是要完整的開發TWA,而是首先實現Chari BFF的功能。
接入BFF的好處
對于團隊來說:
- 業務支持變多
- 溝通協作變少
- 解決問題變快
對于個人來說:
- 更合理分工
- 做BFF可以拓展知識面
接入BFF的壞處:
- 組織決定了架構的復雜度
- 前期學習成本高,短期成為資源瓶頸
可能遇到的問題和可能的解決方法
參考
- Pattern: Backends For Frontends@samnewman
- 為什么互聯網公司開始用node.js做web服務的中間件?有什么好處嗎?@知乎
- Backend For Frontend@黯羽輕揚
- 螞蟻財富的BFF實踐.pdf@alipayobjects
- 微服務架構:BFF和網關是如何演化出來的@10條
- Developer Experience First —— TWA 的理念與實踐@知乎專欄
- Techless Web Application 的理念與實踐 — 不四@優酷
- 02_SEEConf_TWA的理念與實踐_不四.pdf@語雀
- Node 在有贊的實踐@掘金
- 聊聊 Node.js RPC(一)— 協議@語雀
- 聊聊 Node.js RPC(二)— 服務發現@語雀
總結
- 上一篇: 转:集群和分布式的区别
- 下一篇: (转)贫血和富血