存在多個不同註冊中心的時候,如何平滑的統一註冊中心?

程式猿DD發表於2021-05-27

這幾天在不同的微信群和社群裡連續碰到了類似的問題:

比如spring4all的帖子:http://bbs.spring4all.com/thread/21

又比如今天在秦總的群裡也進行了類似的討論。

雖然描述不同,但核心都圍繞著一個問題:兩個不同註冊中心下的服務要如何互相呼叫?

下面就針對這個問題,展開說說我的思考、實踐與建議。

為什麼會有這樣的場景?

先來說說背景問題,有的群友在看到這類問題的時候,第一反應就是怎麼用多個註冊中心,是不是蛋疼了瞎搞的?

顯然有點腦子的人都不會這樣做!那麼為什麼會存在這樣的場景呢,通常都是這樣演變而來的:

  1. 缺少統一的基礎技術平臺管理,幾乎所有做大的企業都會碰到這樣的問題。為了業務野蠻發展的時期,技術團隊是很少有精力去做這些治理的,通過系統邊界劃分好之後,因為系統與系統間的互動通過協議定義規範就好,每個系統內部的技術棧根據團隊特性選擇自己最擅長的就行,並不需要去統一就能又好又快的去完成各個系統的建設。所以,不同的系統選擇不同的註冊中心來治理自己的服務,並沒有什麼不妥。

  2. 隨著業務的發展,業務需要調整,架構需要進化,複雜的系統關係(以往我們自己開發的系統,併購進來的系統,外部採購的系統)需要被重建。不論是以微服務的方式,還是中臺的方式去重新劃分系統邊界,勢必要對現有服務做重新規劃與治理。

  3. 由於系統複雜,我們沒法一步就位,只能一點點的往改造目標去轉變。勢必會存在一個新老共存,逐步轉化的演進過程。為了能夠平滑的過渡改造的過程,我們第一個想到的就是先把服務治理統一起來,讓所有內部服務都可以簡單和便捷的發現彼此並能夠互相呼叫。

於是,就有了文首大家討論的這種場景。所以,這是一個架構演進的過程產物,並不是設計不好才出來的怪胎。

兩種統一服務治理的思路

方案一:在業務服務端,實現多註冊中心的註冊與發現

這種方式就是文首,大家所提問題的方案,實現這種方案涉及幾點核心問題的解決:

  1. 服務註冊的擴充套件:我們知道Spring Cloud的序號產生器制是對單註冊中心的,同時配套的發現也一樣。我們並不能通過多配置一套服務發現介面的實現來實現多註冊中心的實現。所以,你需要以一套主註冊中心為Spring Cloud自身的Bean實現,外圍需要另外去學多套(根據註冊中心數量)註冊客戶端的實現。

  2. 服務發現的擴充套件:對於非主註冊中心的註冊操作實現了一套,那麼發現機制也要實現一套。同時,因為這裡的服務發現,並不與Spring Cloud的服務發現機制繫結,所以這些服務並不會進入到Spring Cloud配置的註冊中心下的ServiceList和對應的ServerList裡。所以在服務發現模組,需要自己把這些外部註冊中心獲取的服務和例項加入到主註冊中心下的ServiceList和ServerList裡。同時,這裡需要注意的幾個點:

  • 因為業務服務往每個註冊中心裡都註冊了,所以在發現的時候,是會有重疊的,這裡要做好去重。
  • 對於服務名稱的管理也需要防重,不同系統下有一些比如使用者中心之類的服務命名是很容易衝突的。通常可以把系統編碼做字首來加工服務名,以保證融合後不存在重複的出現。

通過這樣一頓操作,每個業務服務與所有註冊中心都建立了聯絡,原本處於不同系統的各種服務也都能互相發現並實現互相呼叫了。

方案二:在各個註冊中心之間,實現服務資料的同步

這種方法是新建一個註冊中心同步的服務,它的任務很簡單,就是把每個註冊中心上的服務資訊同步到其他註冊中心上,同時監聽每個註冊中心的變化以保持所有不同註冊中間都包含了所有系統下的服務。

在這種情況下,只要是Spring Cloud構建的業務服務,那麼就只需要逐步的更換註冊中心的依賴,就能輕鬆的把原本處於不同註冊中心下的服務,轉移到同一註冊中心下的服務了。

兩種思路的優缺點比較

上面所述兩種方案的大致優缺點如下:

方案一 方案二
優點 不需增加部署成本 業務服務侵入性小
缺點 業務服務侵入性大 需要增加部署成本

當然,對於方案二也會有一些複雜情況,如果對註冊過程有一些特殊定製的,會需要做一些擴充套件相容。但比起第一種實現方式來說,在業務應用側的邏輯複雜度植入是非常小的。

同時,因為要統一服務治理,那麼事後最終狀態往往就是隻保留最後想要集中維護的註冊中心的,這個時候。如果採用第一種方案,那麼勢必還要去重新調整註冊與發現機制,將要淘汰的註冊與發現邏輯去除,又是一件比較複雜的事情。

所以,綜合比較這兩種方法方法來說。個人認為採用方案二,同步註冊中心的資料來完成統一服務治理的任務,要比方案一更加穩妥,對於業務開發的影響面最小。雖然會引入一些部署成本,但這些成本對於一個多系統的基礎下,那是微乎其微的。

那麼,大家是否有碰到類似的問題呢?又有什麼好的方案呢?留言一起討論下吧!如果你想與更多有趣的靈魂碰撞,也可以加入我們的技術交流群一起探討我們的技術人生!

歡迎關注我的公眾號:程式猿DD,分享外面看不到的乾貨與思考!

相關文章