探索原味 BFF 模式

BFF — Backend For Frontends,經典分佈式架構設計模式之一。我在學習和工作經驗累積中,逐漸加深了對 BFF 的理解。作爲一種模式,它具有一些更加確切的使用場景,和一些能匹配的特定問題。

在本篇文章中,你們會與我一起穿越回 BFF 誕生的歷史中,尋找其起源。並一同探索和學習這個在分佈式系統中出鏡率極高的架構模式。

尋找歷史的線頭

在毫無頭緒的情況下,我們可以首先從 Thoughtworks 技術雷達中 BFF 的條目入手,去找到一些歷史的蛛絲馬跡。BFF 條目的發佈時間是在 2015 年 11 月 10 日。從這個信息我們可以獲知,BFF 在歷史嶄露頭角應該是在 2015 年 。

緊接着,在谷歌搜索關鍵字 Backend for Frontends 以及將時間範圍限定在 2015 年 1 月 1 日到 2015 年 11 月 10 日。通過對比搜索結果的時間,我們可以輕易發現最早出現 Backend for Frontends 詞條的文章。文中提到,BFF 這個名字是由當時團隊 Tech Leader Nick Fisher 首次提出,通過投票獲得了內部團隊的認可。好了,我們現在獲得了一個非常具體的證據。作爲嚴謹的技術工作者,我們找到其他的交叉證據,提高這個結論的置信度。

非常幸運的是,在另一篇 2015 年的 Thoughtworks 洞見文章中也提到了與上面證據相同的內容。終於,我們可以說 BFF 模式是在解決 SoundCloud 的分佈式系統問題中首次出現。下面,讓我們一起回到 BFF 第一次發揮威力的現場吧。

神功初成

爲了能讓大家更容易瞭解到 SoundCloud 當年究竟遇到了什麼樣的挑戰,我會在下面通過分類分項來列舉情況以及進行分析。

背景:

主要動機:

挑戰:

通過分析上面的各種情況,可以得出當時 SoundCloud 後端團隊面對如下幾個問題:

這三個問題在後端團隊進行微服務改造中往往也會遇到。讓我們一起看看,當年的 SoundCloud 團隊在面臨同樣的問題時,是如何一步步見招拆招,摸索出 BFF 模式 這個內功心法的。

演進之路

接下來,BFF 模式演進這一分是由客戶端團隊獲得的。由於他們是 API 的消費者, 可以將不同服務進行多次邏輯調用,混合到後端的用戶配置(UserProfile)文件中。這樣避免了對後端服務多次不同的調用,實現客戶端對單個資源的簡單請求。這將簡化客戶端代碼並提高整體性能,例如:

後端團隊接受了這個邏輯,並開始試驗這個方式。他們在 BFF 中編寫了很多 Presentation Model。在完成一部分任務後,後端團隊突然意識到 BFF 不只是被客戶端使用的 API ,它本身就是申請的一部分。BFF 新的形態出現了,具體如下圖所示:

隨着時間推移,SoundCloud 的 BFF 也在增加。他們已經在生產環境同時維護着 5 個 BFF 了。爲了進一步提高生產力,減少不必要的重複。用戶配置(User Profile) 被從每個不同的微服務中抽取出來,變成一個獨立的在 Services 與 BFF 之間的應用服務(Application Service)。

SoundCloud 的 BFF 依然隨着時間在橫向增長,不同的是這種橫向增長不會再引起任何問題了。最終,BFF 模式的架構演變成與我們現在使用的幾乎一致了。架構如下圖:

總結

我們在維護和使用分佈式架構,同時面對多客戶端時,BFF 模式提供了一種很好的架構模式,使後端團隊在構建面向客戶端的複雜需求時,能夠掌控自己的命運。並且,這種自主性對於快速迭代的客戶端應用程序,能夠提供快速而良好的體驗。通過支持持續的演進和變化,這種模式可以將相同變化趨勢的消費者行爲,限制在一個可控範圍內。使他們變得更容易合作和改變,並且更好滿足不同客戶端的特性需求。

在系統架構中,因爲離需求頻繁變化的前端比較近(網絡和組織架構上),BFF 很容易野蠻生長,成爲各種 “妥協” 的自留地,在使用的過程中,我們需要明確架構中各層相關的職能和邊界。同時,如果確實有不得不去做的一些 “妥協”,我們也一定要用技術債的方式,繼續跟蹤和管理,避免“妥協” 越來越多以後,BFF 從一個解決不同變化速率和需求的適配器,變成分佈式單體的一個轉化器。

我們往往會在系統設計之初犯下一個錯誤,那便是希望所有東西在一開始都是可複用的。這種思路會給系統後續的開發和維護帶來巨大的挑戰,挑戰可能是來自應用間的協調,也可能是兼顧複用帶來的高工作量。特別是在維護多個客戶端或消費者的場景下會帶來更大的困難。我們應該在考慮通用用法之前,先專注於功能和特定用例。在瞭解系統現狀的主次和具體情況後,再針對性地區分需要通用和特殊處理的部分。這種系統設計和開發的思路和方式,使我們能夠擁抱變化,立於演進的不敗之地。

參考文獻


本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/deu_LJ8KZVCCWGlCve-yGA