在《技術中臺與業務中臺都是啥玩意》一文中留下一個問題:BFF是啥?爲啥在API網關和業務中臺之間加入了一層BFF?考慮到在實際工做中,個人大部分同事都問過這個問題,這裏我也總結一下進行答覆。html
1、從一個MyShop開始提及
爲了講清BFF是個啥,這裏引用我在波波老師的課程《Spring Boot與K8s雲原生應用開發》中學到的一個案例,來跟你們分享一下,並盡力說清楚BFF是啥,又是如何演化出來的。前端
假設咱們在一個開發團隊中,開發了一個叫作MyShop的電商項目,它採用的是微服務的架構風格。它經歷過幾回架構調整,咱們就跟着它的調整來看看BFF是怎麼演化出來的。程序員
假設v1版本在七八年以前,MyShop已經採用了服務化的架構,它的客戶端也主要仍是以傳統的Web應用爲主。在當時,它的SOA架構已經算是跟上了潮流。後端
轉眼之間,來到了四五年前,MyShop升級爲了v2版本,它的架構以下圖所示:安全
能夠看到,這個時候已經進入了移動互聯網時代,MyShop爲了緊跟時代,也推出了本身的無線應用App。爲了可以儘快上線,MyShop團隊的架構師設計了v2架構,它爲App端新增了一個Nginx反向代理,可使App入口直接訪問API微服務。架構
可是,這個急於求成的v2架構存在如下問題:負載均衡
(1)App端和內部的API微服務存在一個強耦合的關係(包括接口耦合和域名耦合),任何一邊的變化都會對另一邊形成必定影響。框架
(2)每一個對外暴露的服務,都須要新的域名,而域名是須要買的,是須要承擔成本的。前後端分離
(3)內部的API微服務一股腦地暴露在了公網上面,存在很大的安全風險。運維
(4)App客戶端須要開發大量的聚合裁剪的邏輯,客戶端很重且重複勞動。(所謂聚合裁剪,解釋一下,聚合就是一次須要從多個微服務獲取數據進行整合使用,而裁剪就是須要對微服務返回的數據進行過濾,可能只會用到其中一部分的字段數據)
2、引入BFF的MyShop v2.5
因爲v2版本存在的問題太多,因而架構團隊決定在Nginx和內部API微服務之間引入一層無線BFF(英文全稱:Backend For Frontend,指爲前端應用開發的後端服務)來解決這個問題,也就有了下面的v2.5版本的架構。
咱們能夠將BFF看作是一個後端微服務的代理服務,它主要作聚合和裁剪的邏輯,方便客戶端接入和訪問。能夠看到,引入了BFF以後,下降了App端與後端微服務之間的耦合,從而避免了v2版本提到的強耦合問題。此外,App端只須要知道BFF的域名便可,內部微服務也躲在BFF以後不須要暴露在公網之上。
因爲v2.5版本解決了不少問題,所以成功上線,也爲MyShop無線業務的發展作了很大的支持。
可是,隨着業務的不斷快速發展,單塊的無線BFF堆積了大量的不一樣業務線的邏輯變得愈來愈臃腫,升級維護也變得愈來愈困難。此外,根據康威法則,單塊的無線BFF和多團隊也出現了不匹配的問題,即團隊之間溝通成本變低,交付成本也就會變高。最後,無線BFF裏面除了多業務線的聚合裁剪邏輯,還引入了Cross-Cutting(跨橫切面)的邏輯,好比安全認證、日誌監控、限流熔斷等等。隨着時間的推移,代碼變得愈來愈複雜,技術棧越堆越多,開發效率也不斷降低。(固然,還有單點問題等等,這裏就很少贅述了)
3、網關+BFF模式的MyShop v3
爲了解決v2.5版本存在的問題,架構團隊通過進一步思考,一方面決定將單塊的無線BFF進行解耦拆分,針對不一樣的業務線引入獨立的微服務集羣。另外一方面,決定在無線BFF和Nginx之間再引入一個新的角色:API網關,並將Cross-Cutting的職責轉移到API網關上。自此,v3架構出爐,以下圖所示:
v3架構下,BFF按照團隊或業務線的邊界進行劃分,每一個業務線團隊能夠並行各自開發和交付BFF。而網關則由單獨的中間件或框架團隊進行開發和維護,它專一於路由轉發和Cross-Cutting層面的功能建設,讓業務線團隊專一於業務邏輯的開發。咱們.NET程序員所熟知的Ocelot網關項目(對,就是張隊參與貢獻的那個網關項目),就幫助咱們實現了路由轉發和Cross-Cutting的功能,例如限流熔斷、集中鑑權(例如集成IdentityServer)、負載均衡、調用追蹤等。
4、乘風破浪的MyShop v4
最近一兩年呢,MyShop團隊迎來了新的業務和技術的發展需求,要開放內部的企業級能力建設OpenAPI開放平臺,還想要藉助第三方的力量在MyShop平臺上進行創新打造生態從而豐富MyShop的應用形態。此外,SPA單頁應用、H5先後端分離應用等多類型的應用客戶端也須要接入。架構團隊設計了一個以下圖所示的v4架構,從而知足快速發展的已有和將來可能的需求:
在v4架構下,移除了原來偏運維層面的Nginx反向代理,轉而統一使用可變成型較強的網關做爲客戶端應用入口,固然這裏引入了一些其餘的LB服務作了網關層的負載均衡。這裏的網關也進行解耦拆分,針對不一樣的客戶端應用場景,分爲了四個類型,如開放平臺網關、H5網關、無線網關和Web應用網關。而BFF層面,也根據業務線拆分爲了無線BFF、H5 BFF及開放平臺BFF。整個架構層次清晰,職責分明,是一種靈活的、方便支持MyShop業務快速發展的架構。相信看到這裏,你大概應該明白了BFF是個啥,它在微服務架構中的位置和做用,以及它是如何演化出來的。
畫外音:若是還沒明白,那就再看一遍!
5、我司還處於v3階段
剛剛經過MyShop的案例架構演化,講解了BFF和網關是如何演化出來的。那麼,你可能會問,我司的架構處在哪一個階段。這裏,回答一下,還在v3階段。
能夠從這個技術體系圖中看到,做爲應用服務層的API服務就是BFF,他們會從基礎業務服務如客戶服務、訂單服務、產品服務等微服務中獲取數據,進行必定的聚合和裁剪返回個某個具體業務線的前端應用,前端應用多是SPA也多是H5應用。BFF層的API服務,咱們在實踐中大部分都使用了ASP.NET Core進行開發,同時也在嘗試使用Go進行開發,也讓前端有興趣的同事引入進來用Go進行BFF的開發。可是,在基礎服務層面即前面所說的業務中臺層,仍是由後端同事使用ASP.NET Core開發,確保質量。API網關層面,咱們使用的是Ocelot,集成了鑑權認證等工做,前端統一隻須要記住網關的域名便可,帶上合法的token訪問便可獲取數據返回。不少人說Ocelot性能低建議使用Kong,可是我司業務量小啊,因此目前沒啥問題,用得好好的。內部微服務之間的相互調用,咱們目前也是走了API網關(區別於外部應用訪問的網關,這裏我稱之爲內部網關),不過爲了方便(實際上是懶),咱們對於內部信任的服務間調用,沒有走JWT認證,固然也能夠選擇Client Credentials(客戶端憑證)模式。對於現階段的咱們的架構來講,只能說是夠用,由於業務量真的不大,也不必爲了上所謂的高性能高可用架構作過多的設計,對傳統家居裝飾行業的企業來講,IT先知足業務支持業務快速發展吧。數字化轉型,也並非一次就吃個胖子,慢慢演進吧。最後,想着是快答,竟然也洋洋灑灑寫了這麼多,但願對你有所幫助吧!
畫外音:若是看到這裏,你都不點個贊/在看,有點那啥了...