前端網關的思考

在微服務體系結構中,客戶端應用一般須要使用來自多個微服務的功能,在小型應用程序中,一般會使用客戶端到微服務直接通訊的方式:前端

gateway.png

在此種模式下,每一個 Microservice 可能有一個不一樣的 TCP 端口,或者配置了不一樣的 URL 地址。node

在一個基於微服務的小型應用程序中,它能基本知足,尤爲是在客戶端應用爲服務器端 Web 應用程序(如 ASP.NET MVC 應用)的狀況下。 可是,若要生成基於微服務的大型複雜應用程序(例如處理大量微服務類型),尤爲是客戶端應用是遠程移動應用或 SPA Web 應用程序時,該方法將面臨一些問題:git

  • 強耦合:各 App 與內部微服務之間強偶合,任何一邊變換均可能對另一邊形成影響。
  • 安全性問題:微服務暴露在「外部世界」中,相較於不直接使用內部微服務,這種狀況下攻擊面更大。攻擊面越小,意味着應用程序越安全。
  • 過多的請求:可能某個功能須要調用幾個後端接口請求進行組合後展現。
  • 沒有專爲移動應用適配:多個微服務的 API 設計可能沒法知足不一樣客戶端應用程序的需求。如,移動應用的需求不一樣於 Web 應用,它須要進一步的優化,以便數據響應能更有效。

BFF 架構的誕生

在 Sam NewMan 的一篇文章 Pattern: Backends For Frontends 中,最先提出 BFF 概念,認爲 BFF 是複雜應用的天然產物。BFF 便是用戶體驗適配層,根據不一樣的設備類型,來返回不一樣的結果。github

gateway2.png

根據業務邊界和客戶端應用劃分的 BFF 層,能提供諸如反向代理、接口聚會、裁剪等功能,除此以外,BFF 層的出現讓領域模型與頁面數據更好的解耦,讓彼此更高效。後端

理想狀況下,前端頁面與 BFF 層由不一樣的同窗開發,前端人員專一於頁面數據;開發 BFF 的同窗,則按需聚合、裁剪數據返回給前端。可是現實每每是 BFF 以及頁面數據都由前端人員來開發,尤爲是對於作中後臺的系統來講,一個前端同窗既要寫複雜的業務邏輯,同時又負責 BFF 層的開發,長此以往,BFF 層的存在,退化到僅僅是一層代理,如同虛設。緩存

咱們也在尋找一種適合於咱們本身業務模型的架構模式。安全

API 網關的介入

實踐事後,咱們決定去掉 BFF 層,而引入更爲通用的從屬於前端的 API 網關層(注:BFF 是 API 網關模式的一個特例):服務器

gateway4.png

在這個 API 網關層中,咱們再也不作數據的聚合與裁剪,由於這些對於一箇中後臺的內部系統來講,並不重要。微信

使用 API 網關,也着實解決了咱們的一些痛點:架構

  • 解耦合,API 網關有一個重要的功能,就是將用戶的請求轉發給後端的服務器,微服務進行重構時,只須要改 API 網關中的映射關係便可,無需修改前端代碼。
  • 前端代碼易於維護。引入 API 網關之後,全部的前端接口都請求至 API 網關,由網關負責具體請求的服務器,而無需維護大量的 URL。
  • 日誌,全部的請求都是由網關處理,日誌比較完善,好比接口耗時、請求方式、請求 IP、參數等。同時,還可使用 traceId,追蹤整個鏈路的調用,方便排查問題。
  • 其餘一些,好比限流和緩存等,在 API Gateway 也能夠實現。

固然,咱們也有一些 2C 的產品,這些產品中,有一部分咱們是使用 Vue/React SSR 技術,

gateway7.png

在這個 Vue/React SSR 中,必定程度上,也充當着 BFF 層的做用。

總結

咱們並無使用傳統的 Client->API網關->BFF->微服務 架構模式,面對特殊的業務場景(大量的中後臺應用),咱們取消了 BFF 層,使用了 Client->API網關->微服務,而對於 2C 的應用使用 Clent(SSR)->API網關->微服務 這樣架構模式。

固然,咱們也在嘗試、探索基於 Serverless 的 Gateway 架構:

640.jpg

(圖片來自:github.com/nodejh/node…

Serverless 在更多、更復雜領域的實踐值得期待。


更多文章,請關注公衆號:

微信服務號
相關文章
相關標籤/搜索