註冊中心與API閘道器不是這樣用的!

程式猿DD發表於2021-04-29

之前在做顧問和諮詢專案的時候,見到了一種非常經典的關於API閘道器和註冊中心的錯誤用法。這個案例在我的星球裡已經分享過,沒想到最近又碰到了兩個類似的使用姿勢。也許這樣的問題還存在不少團隊的應用中,所以拿出來再分享一下,希望可以幫助讀者更好的理解註冊中心與API閘道器的作用,並將它們用對地方!

在微服務架構中,我們都會使用API閘道器來作為暴露服務的唯一出口。這樣可以將與業務無關的各項控制,集中的在API閘道器中進行統一管理,從而使得業務服務可以更加專注於業務領域本身。

而在微服務構建的系統內部,各個服務之間的排程,我們通常採用註冊中心和客戶端負載均衡的方式來實現服務之間的呼叫。

所以,大致的結構是這樣子的:

在這樣的架構實踐中,註冊中心和API閘道器的功能,主要有以下兩點:

  1. API閘道器通過註冊中心發現所有後端服務,從來實現動態代理
  2. 後端服務叢集間,通過註冊中心互相發現對方,而實現直接呼叫(通常使用Ribbon、Feign這些框架)

下面就來具體說說今天的主角(錯誤案例),先上圖:

注意圖中的兩個地方:

  1. 存在兩套閘道器,一套對內訪問、一套對外訪問
  2. 對內訪問的閘道器實際就是起到了一個代理作用,較之前的圖對比以下,就知道,這個方案中並沒有利用到服務治理機制去直接讓服務A呼叫服務B,而是通過閘道器去做了一次代理。

更震驚的是,在我看到程式碼的時候,他們居然也是用feign來編寫服務間呼叫的,但在配置請求路徑的時候,是使用在內部API閘道器上配置的二級域名來實現(比如:http://service-name.didispace.com/api-path,這裡service-name對應不同的服務名),而熟悉Spring Cloud的讀者都知道,其實service-name.didispace.com這部分直接用服務名替代就可以了...是不是瞬間有種脫褲子放x的感覺?

如果這樣來使用的話,其實引入註冊中心的用處就很小了,實際上只有給兩個閘道器提供了集中的後端服務發現功能。如果要實現這種功能,其實註冊中心都可以不需要,每個服務都直接上報地址給閘道器就好了,架構會更加簡單。

同時,在這樣的實現方式之下,內部呼叫都要經過內部閘道器多一跳的排程過程,除了要多出內部閘道器的部署資源之外,每一次內部呼叫的時間開銷實際上都大了。所以這樣的用法是非常不推薦的!

對於API閘道器的定位,還是以作為對外出口的管理為最佳,內部的代理呼叫,均交給服務註冊與發現機制 + 客戶端負載均衡就ok了。沒有必要再增加一層代理,不但增加部署成本,同時還會降低的效能。完全是賠了夫人又折兵的做法,非常不可取!

除非有一種情況,如果你的業務叢集很大,對前端暴露用一套閘道器,同時後端服務有幾千幾萬,由很多個不同的團隊在維護,那麼在團隊的邊界處設立內部的閘道器,那還是合理的。同時這種情況下,對於註冊中心,按團隊做隔離也是有必要的。因為這樣可以分而治之,更好的做好介面的訪問控制與管理。但是,如果你本身服務不多,團隊也不大,那就別折騰這麼複雜的架構了,越複雜穩定性就越難保障,這點一定要平衡好。

最後,大家結合自己團隊的註冊中心與API閘道器應用是否有犯一樣的問題呢?或者如果有其他問題與疑問,不妨留言交流一下?也可以加入我們的技術交流群一起探討技術問題!

擴充閱讀

相關文章