為什麼微服務一定要有API閘道器?

語言: CN / TW / HK

微服務不能沒有閘道器,就如同 Java 程式設計師不能沒有IDEA、Eclipse。為什麼呢?

之所以閘道器對微服務這麼重要,主要有以下幾點原因:

1. 解決 API 放哪裡的問題

要知道,採用微服務架構的系統本身是由很多的獨立服務單元組合起來的。而客戶端要呼叫系統,則必須通過系統提供的各種對外開放的功能 API 來實現。

問題來了,這些 API 要放在哪裡呢?直接放在組成系統的服務單元上行不行?

比如,在一套電商系統上,關於訂單相關的 API ,放在組成訂單服務的服務單元上;風控服務的 API ,放在組成風控服務的服務單元上。

為什麼微服務一定要有API閘道器?

好,咱們假設有這麼一個場景,有一位使用者想在這套電商系統上檢視下商品詳情。那麼,這個檢視商品詳情的操作,就可能:

  • 呼叫商品服務的 API 獲取商品描述
  • 呼叫評價服務的 API 獲取相關評價
  • 呼叫商家服務的 API 獲取商家資訊
  • 呼叫禮券服務的 API 獲取相關禮券
  • ……

為什麼微服務一定要有API閘道器?

可以看到,就這麼一個商品檢視操作,就可能會呼叫許多服務的 API。

那這些 API 如果全部分散到各個服務單元上,供客戶端呼叫,像檢視商品這麼簡單的一次操作,客戶端就可能需要遠端訪問好幾次甚至十幾次伺服器。

微服務員自己有講究把 API 的粒度劃分得很細,也就是說,可能從商品服務上呼叫商品資訊,不止是呼叫一次商品服務就夠了,很可能需要多次對商品服務的不同 API 進行呼叫,才能獲取到足夠的資料。

這樣一來,客戶端需要訪問伺服器的次數就更多了,可能十幾次都不夠,得幾十次。

這種多次訪問伺服器的行為,會極大延遲客戶端的介面響應時間,很不現實。

所以,把 API 放到各個業務相關的服務單元上,看上去問題很大。

那為什麼引入閘道器就能解決這個問題呢?

因為引入閘道器,就相當於在客戶端和微服務之間加了一層隔離。通常,閘道器本身會和各個服務單元處於同一個機房,這樣,客戶端做業務操作的時候,只需要訪問一次閘道器。然後剩下的事情,再由閘道器分別訪問同在一個機房的不同的服務,再把拿到的資料統一在閘道器封裝好,返回給客戶端就好。

為什麼微服務一定要有API閘道器?

2. 解決邊緣功能整合的問題

在一套微服務組成的系統裡,除了必須的業務功能以外,還有為了系統自身的健壯與安全,以及微服務本身的管理,而必須引入的一些非業務功能。對於這些非業務又很重要的功能,我們統稱為邊緣功能。

還是拿電商系統為例,我們來看一些重要的邊緣功能。

假設因為我們做了一次非常大的促銷活動,導致流量過大,系統承載不了了。此時,為了保證系統本身的穩定,我們就需要把一些承載不了的流量給通過各種手段消化掉,一般的做法有三種:

  • 限流:通過令牌桶等演算法,把一些額外的流量擋在系統外面,不讓其訪問。
  • 降級:由於系統可能已經過載了,此時,我們就放棄處理一些服務和頁面的請求或者進行簡單處理,比如直接返回一個報錯。
  • 熔斷:有些時候,系統過載過度或者上線出了問題 bug,降級都解決不了問題。比如,快取失效了,導致大量請求頻繁訪問了資料庫,而這種頻繁訪問資料庫可能造成了大量的 IO 操作,結果又影響了資料庫所在的作業系統,同時,這個作業系統上又有著別的重要服務,直接也被影響了。對於這種連鎖反應,我們稱之為雪崩。而為了防止雪崩,我們就會堅決把快取失效導致資料庫被頻繁訪問的服務給停掉,這就是熔斷。

可以看到,像限流、降級、熔斷這些系統保障策略,最合適的地方應該是有一個集中的請求入口點,就像古時候,老百姓進城需要過城門那樣。

當系統出現問題的時候,直接就在這個入口點做相應的操作即可。

  • 限流,就直接在這個入口點限制後續請求。
  • 降級,就直接在這個入口點判斷請求想要訪問的服務或者頁面,直接報錯返回。
  • 熔斷,就直接在這個入口點,斷開所有訪問特定服務的請求連線,然後再把後繼對特定服務的訪問,也統統攔在門外。

在電商系統裡,有很多特殊場景的介面,需要受到嚴格的限制。

比如,支付介面,訪問它就需要認證和許可權控制。又比如,對於系統的訪問,有時候不能讓國外的人去訪問國內的網站,這就需要限制客戶端的訪問 IP,所以系統還需要認證和授權功能。

那這種認證和授權也是最合適放在請求的一個集中入口點,統一實現。

還記得上面咱們說過的閘道器的 API 統一存放嗎?我們只需要對這些 API 做對應的許可權設定,當請求訪問特殊場景介面的時候,必定會通過 API 訪問。所以,限制介面的訪問,本質上就是對特定 API 的限制,那麼,放在閘道器再合適不過了。

現實裡,我們有時候需要把線上的流量映象出來,轉發到灰度環境,利用這些映象出來的流量既可以用於小範圍測試,又可以更好的評估系統所能承載的最大吞吐量,也因此,系統需要有一個統一入口做分流。

可以看到,無論是系統需要的保障策略,認證授權,還是流量分流等功能,都應該放到一個統一的請求入口處才能得到最好的實現。閘道器恰好就承擔了這麼個統一請求入口的角色。

所以,對於微服務中,林林總總的邊緣功能,往往會通過外掛的形式,整合在 API 閘道器中。

3. 解耦了客戶端和後端微服務

一套專案,在使用微服務模式的初期,往往後端變化是十分頻繁的。

頻繁變化的原因有很多,像業務領域劃分不合適啊,像某個業務模組急速膨脹啊,都可能導致後端微服務的劇烈變化。

在這種情況下,如果沒有閘道器,很可能就會出現客戶端需要被迫隨著後端的變化而變化的情況。

比如,在電商系統裡,初期我們很可能會把風控服務做得非常小。隨著業務的發展,風控服務越來越龐大,此時,風控服務就可能被分解為決策引擎和分析中心等更多更細的服務。

在電商裡,風控往往是下單、支付等操作的必要前置操作。如果沒有閘道器去分隔開客戶端和微服務,客戶端直接和風控服務打交道,那麼風控服務拆分,API 必然不會穩定,API 的變化,自然會引發呼叫 API 客戶端程式碼的變化。

有了閘道器之後,情況就好了很多了。當風控服務本身頻繁變化的時候,我們只需要改動閘道器的程式碼就好。而伺服器程式碼的升級可是遠遠要比客戶端程式碼的升級容易太多了。