爲什麼微服務一定要有 API 網關?
微服務不能沒有網關,就如同 Java 程序員不能沒有 IDEA、Eclipse。爲什麼呢?
之所以網關對微服務這麼重要,主要有以下幾點原因:
- 解決 API 放哪裏的問題
要知道,採用微服務架構的系統本身是由很多的獨立服務單元組合起來的。而客戶端要調用系統,則必須通過系統提供的各種對外開放的 API 來實現。
問題來了,這些 API 要放在哪裏呢?直接放在組成系統的服務單元上行不行?
比如,在一套電商系統上,關於訂單相關的 API ,放在組成訂單服務的服務單元上;風控服務的 API ,放在組成風控服務的服務單元上。
好,咱們假設有這麼一個場景,有一位用戶想在這套電商系統上查看下商品詳情。那麼,這個查看商品詳情的操作,就可能:
-
調用商品服務的 API 獲取商品描述
-
調用評價服務的 API 獲取相關評價
-
調用商家服務的 API 獲取商家信息
-
調用禮券服務的 API 獲取相關禮券
-
……
可以看到,就這麼一個商品查看操作,就可能會調用許多服務的 API。
那這些 API 如果全部分散到各個服務單元上,供客戶端調用,像查看商品這麼簡單的一次操作,客戶端就可能需要遠程訪問好幾次甚至十幾次服務器。
微服務自己又講究把 API 的粒度劃分的很細,也就是說,可能從商品服務上調用商品信息,不止是調用一次商品服務就夠了,很可能需要多次對商品服務的不同 API 進行調用,才能獲取到足夠的數據。
這樣一來,客戶端需要訪問服務器的次數就更多了,可能十幾次都不夠,得幾十次。
這種多次訪問服務器的行爲,會極大延遲客戶端的界面響應時間,很不現實。
所以,把 API 放到各個業務相關的服務單元上,看上去問題很大。
那爲什麼引入網關就能解決這個問題呢?
因爲引入網關,就相當於在客戶端和微服務之間加了一層隔離。通常,網關本身會和各個服務單元處於同一個機房,這樣,客戶端做業務操作的時候,只需要訪問一次網關。然後剩下的事情,再由網關分別訪問同在一個機房的不同的服務,再把拿到的數據統一在網關封裝好,返回給客戶端就好。
- 解決邊緣功能集成的問題
在一套微服務組成的系統裏,除了必須的業務功能以外,還有爲了系統自身的健壯與安全,以及微服務本身的管理,而必須引入的一些非業務功能。對於這些非業務又很重要的功能,我們統稱爲邊緣功能。
還是拿電商系統爲例,我們來看一些重要的邊緣功能。
假設因爲我們做了一次非常大的促銷活動,導致流量過大,系統承載不了了。此時,爲了保證系統本身的穩定,我們就需要把一些承載不了的流量給通過各種手段消化掉,一般的做法有三種:
-
限流:通過令牌桶等算法,把一些額外的流量擋在系統外面,不讓其訪問。
-
降級:由於系統可能已經過載了,此時,我們就放棄處理一些服務和頁面的請求或者僅簡單處理,比如直接返回一個報錯。
-
熔斷:有些時候,系統過載過度或者上線出了 bug,降級都解決不了問題。比如,緩存失效了,導致大量請求頻繁訪問了數據庫,而這種頻繁訪問數據庫可能造成了大量的 IO 操作,結果又去影響了數據庫所在的操作系統,同時,這個操作系統上又有着別的重要服務,直接也被影響了。對於這種連鎖反應,我們稱之爲雪崩。而爲了防止雪崩,我們就會堅決把緩存失效導致數據庫被頻繁訪問的服務給停掉,這就是熔斷。
可以看到,像限流、降級、熔斷這些系統保障策略,最合適的地方應該是有一個集中的請求入口點,就像古時候,老百姓進城需要過城門那樣。
當系統出現問題的時候,直接就在這個入口點做相應的操作即可。
-
限流,就直接在這個入口點限制後續請求。
-
降級,就直接在這個入口點判斷請求想要訪問的服務或者頁面,直接報錯返回。
-
熔斷,就直接在這個入口點,斷開所有訪問特定服務的請求連接,然後再把後繼對特定服務的訪問,也統統攔在門外。
在電商系統裏,有很多特殊場景的接口,需要受到嚴格的限制。
比如,支付接口,訪問它就需要認證和權限控制。又比如,對於系統的訪問,有時候不能讓國外的去訪問國內的網站,這就需要限制客戶端的訪問 IP,所以系統還需要認證和授權功能。
那這種認證和授權也最合適放在請求的一個集中入口點,統一實現。
還記得上面咱們說過的網關的 API 統一存放嗎?我們只需要對這些 API 做對應的權限設置,當請求訪問特殊場景接口的時候,必定會通過 API 訪問。所以,限制接口的訪問,本質上就是對特定 API 的限制,那麼,放在網關再合適不過了。
現實裏,我們有時候需要把線上的流量鏡像出來,轉發到灰度環境,利用這些鏡像出來的流量既可以用於小範圍測試,又可以更好的評估系統所能承載的最大吞吐量,也因此,系統需要有一個統一入口做分流。
可以看到,無論是系統需要的保障策略,認證授權,還是流量分流等功能,都應該放到一個統一的請求入口處才能得到最好的實現。網關恰好就承擔了這麼個統一請求入口的角色。
所以,對於微服務中,林林總總的邊緣功能,往往會通過插件的形式,集成在 API 網關中。
- 解耦了客戶端和後端微服務
一套項目,在使用微服務模式的初期,往往後端變化是十分頻繁的。
頻繁變化的原因有很多,像業務領域劃分不合適啊,像某個業務模塊急速膨脹啊,都可能導致後端微服務的劇烈變化。
在這種情況下,如果沒有網關,很可能就會出現客戶端需要被迫隨着後端的變化而變化的情況。
比如,在電商系統裏,初期我們很可能會把風控服務做的非常小。隨着業務的發展,風控服務越來越龐大,此時,風控服務就可能被分解爲決策引擎和分析中心等更多更細的服務。
在電商裏,風控往往是下單、支付等操作的必要前置操作。如果沒有網關去分隔開客戶端和微服務,客戶端直接和風控服務打交道,那麼風控服務拆分,API 必然不會穩定,API 的變化,自然會引發調用 API 客戶端代碼的變化。
有了網關之後,情況就好了很多了。當風控服務本身頻繁變化的時候,我們只需要改動網關的代碼就好。而服務器代碼的升級可是遠遠要比客戶端代碼的升級容易太多了。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/U1Y0GS2kgBasfwJlu3XPEw