從0開始學微服務:12 如何將註冊中心落地?

從0開始學微服務:12 如何將註冊中心落地?

專欄第 5 期我給你講了服務註冊和發現的原理,這裡面的核心是服務提供者、服務消費者和註冊中心這三個概念,以及它們之間的交互關係。你可以先回顧一下這幾個關鍵的知識點,如果有不清楚的地方,建議你先返回第 5 期複習一下,再開始今天的學習。

掌握了服務註冊和發現的原理之後,我們就需要考慮如何把註冊中心落地實現。結合前面所講的服務註冊與發現的流程,在落地註冊中心的過程中,我們需要解決一系列的問題,包括如何存儲服務信息、如何註冊節點、如何反註冊、如何查詢節點信息以及如何訂閱服務變更等。這些問題你都知道如何解決嗎?如果還沒答案,沒關係,下面我來給你一一講解。

註冊中心如何存儲服務信息

註冊中心既然是用來存儲服務信息的,那麼服務信息都包含哪些內容呢?

根據我的實踐經驗,服務信息除了包含節點信息(IP 和端口號)以外,還包含其他一些信息,比如請求失敗時重試的次數、請求結果是否壓縮等信息。因此服務信息通常用 JSON 字符串來存儲,包含多個字段,每個字段代表不同的含義。

除此之外,服務一般會分成多個不同的分組,每個分組的目的不同。一般來說有下面幾種分組方式。

  • 核心與非核心,從業務的核心程度來分。
  • 機房,從機房的維度來分。
  • 線上環境與測試環境,從業務場景維度來區分。

所以註冊中心存儲的服務信息一般包含三部分內容:分組、服務名以及節點信息,節點信息又包括節點地址和節點其他信息。從註冊中心中獲取的信息結構大致如下圖所示。

從0開始學微服務:12 如何將註冊中心落地?

具體存儲的時候,一般是按照“服務 - 分組 - 節點信息”三層結構來存儲,可以用下圖來描述。Service 代表服務的具體分組,Cluster 代表服務的接口名,節點信息用 KV 存儲。

從0開始學微服務:12 如何將註冊中心落地?

搞清楚了註冊中心存儲服務信息的原理後,再來看下注冊中心具體是如何工作的,包括四個流程。

  • 服務提供者註冊流程。
  • 服務提供者反註冊流程。
  • 服務消費者查詢流程。
  • 服務消費者訂閱變更流程。

接下來,我來給你具體講解上面四個流程的實現方式。

註冊中心是如何工作的

1. 如何註冊節點

知道了服務的節點信息如何存儲之後,服務註冊流程是怎麼樣的呢?可以用下面這張流程圖來描述。

從0開始學微服務:12 如何將註冊中心落地?

根據我的經驗,服務註冊流程主要有下面幾個步驟:

  • 首先查看要註冊的節點是否在白名單內?如果不在就拋出異常,在的話繼續下一步。
  • 其次要查看註冊的 Cluster(服務的接口名)是否存在?如果不存在就拋出異常,存在的話繼續下一步。
  • 然後要檢查 Service(服務的分組)是否存在?如果不存在則拋出異常,存在的話繼續下一步。
  • 最後將節點信息添加到對應的 Service 和 Cluster 下面的存儲中。

2. 如何反註冊

再來看下服務提供者節點反註冊的流程,可以用下面這張流程圖來描述。

從0開始學微服務:12 如何將註冊中心落地?

根據我的經驗,節點反註冊流程主要包含下面幾個步驟:

  • 查看 Service(服務的分組)是否存在,不存在就拋出異常,存在就繼續下一步。
  • 查看 Cluster(服務的接口名)是否存在,不存在就拋出異常,存在就繼續下一步。
  • 刪除存儲中 Service 和 Cluster 下對應的節點信息。
  • 更新 Cluster 的 sign 值。

3. 如何查詢節點信息

關於服務消費者是如何從註冊中心查詢服務提供者的節點信息,可以用下面這張流程圖來描述。

從0開始學微服務:12 如何將註冊中心落地?

服務消費者查詢節點信息主要分為下面幾個步驟:

  • 首先從 localcache(本機內存)中查找,如果沒有就繼續下一步。這裡為什麼服務消費者要把服務信息存在本機內存呢?主要是因為服務節點信息並不總是時刻變化的,並不需要每一次服務調用都要調用註冊中心獲取最新的節點信息,只需要在本機內存中保留最新的服務提供者的節點列表就可以。
  • 接著從 snapshot(本地快照)中查找,如果沒有就繼續下一步。這裡為什麼服務消費者要在本地磁盤存儲一份服務提供者的節點信息的快照呢?這是因為服務消費者同註冊中心之間的網絡不一定總是可靠的,服務消費者重啟時,本機內存中還不存在服務提供者的節點信息,如果此時調用註冊中心失敗,那麼服務消費者就拿不到服務節點信息了,也就沒法調用了。本地快照就是為了防止這種情況的發生,即使服務消費者重啟後請求註冊中心失敗,依然可以讀取本地快照,獲取到服務節點信息。

4. 如何訂閱服務變更

最後看下,服務消費者如何訂閱服務提供者的變更信息呢?可以用下面這張流程圖來描述。

從0開始學微服務:12 如何將註冊中心落地?

主要分為下面幾個步驟:

  • 服務消費者從註冊中心獲取了服務的信息後,就訂閱了服務的變化,會在本地保留 Cluster 的 sign 值。
  • 服務消費者每隔一段時間,調用 getSign() 函數,從註冊中心獲取服務端該 Cluster 的 sign 值,並與本地保留的 sign 值做對比,如果不一致,就從服務端拉取新的節點信息,並更新 localcache 和 snapshot。

這裡小結一下,以上就是服務註冊和反註冊、服務查詢和服務訂閱變更的基本流程。除此之外,我再給你講下我在實際項目實踐中,實現服務註冊與發現時遇到的幾個問題,希望能給你幫助。

註冊與發現的幾個問題

1. 多註冊中心

理論上對於一個服務消費者來說,同一個註冊中心交互是最簡單的。但是不可避免的是,服務消費者可能訂閱了多個服務,多個服務可能是由多個業務部門提供的,而且每個業務部門都有自己的註冊中心,提供的服務只在自己的註冊中心裡有記錄。這樣的話,就要求服務消費者要具備在啟動時,能夠從多個註冊中心訂閱服務的能力。

根據我的經驗,還有一種情況是,一個服務提供者提供了某個服務,可能作為靜態服務對外提供,有可能又作為動態服務對外提供,這兩個服務部署在不同的註冊中心,所以要求服務提供者在啟動的時候,要能夠同時向多個註冊中心註冊服務。

也就是說,對於服務消費者來說,要能夠同時從多個註冊中心訂閱服務;對於服務提供者來說,要能夠同時向多個註冊中心註冊服務。

2. 並行訂閱服務

通常一個服務消費者訂閱了不止一個服務,在我經歷的一個項目中,一個服務消費者訂閱了幾十個不同的服務,每個服務都有自己的方法列表以及節點列表。服務消費者在服務啟動時,會加載訂閱的服務配置,調用註冊中心的訂閱接口,獲取每個服務的節點列表並初始化連接。

最開始我們採用了串行訂閱的方式,每訂閱一個服務,服務消費者調用一次註冊中心的訂閱接口,獲取這個服務的節點列表並初始化連接,總共需要執行幾十次這樣的過程。在某些服務節點的初始化連接過程中,出現連接超時的情況,後續所有的服務節點的初始化連接都需要等待它完成,導致服務消費者啟動變慢,最後耗費了將近五分鐘時間來完成所有服務節點的初始化連接過程。

後來我們改成了並行訂閱的方式,每訂閱一個服務就單獨用一個線程來處理,這樣的話即使遇到個別服務節點連接超時,其他服務節點的初始化連接也不受影響,最慢也就是這個服務節點的初始化連接耗費的時間,最終所有服務節點的初始化連接耗時控制在了 30 秒以內。

3. 批量反註冊服務

通常一個服務提供者節點提供不止一個服務,所以註冊和反註冊都需要多次調用註冊中心。在與註冊中心的多次交互中,可能由於網絡抖動、註冊中心集群異常等原因,導致個別調用失敗。對於註冊中心來說,偶發的註冊調用失敗對服務調用基本沒有影響,其結果頂多就是某一個服務少了一個可用的節點。但偶發的反註冊調用失敗會導致不可用的節點殘留在註冊中心中,變成“殭屍節點”,但服務消費者端還會把它當成“活節點”,繼續發起調用,最終導致調用失敗。

以前我們的業務中經常遇到這個問題,需要定時去清理註冊中心中的“殭屍節點”。後來我們通過優化反註冊邏輯,對於下線機器、節點銷燬的場景,通過調用註冊中心提供的批量反註冊接口,一次調用就可以把該節點上提供的所有服務同時反註冊掉,從而避免了“殭屍節點”的出現。

4. 服務變更信息增量更新

服務消費者端啟動時,除了會查詢訂閱服務的可用節點列表做初始化連接,還會訂閱服務的變更,每隔一段時間從註冊中心獲取最新的服務節點信息標記 sign,並與本地保存的 sign 值作比對,如果不一樣,就會調用註冊中心獲取最新的服務節點信息。

一般情況下,按照這個過程是沒問題的,但是在網絡頻繁抖動時,服務提供者上報給註冊中心的心跳可能會一會兒失敗一會兒成功,這時候註冊中心就會頻繁更新服務的可用節點信息,導致服務消費者頻繁從註冊中心拉取最新的服務可用節點信息,嚴重時可能產生網絡風暴,導致註冊中心帶寬被打滿。

為了減少服務消費者從註冊中心中拉取的服務可用節點信息的數據量,這個時候可以通過增量更新的方式,註冊中心只返回變化的那部分節點信息,尤其在只有少數節點信息變更時,此舉可以大大減少服務消費者從註冊中心拉取的數據量,從而最大程度避免產生網絡風暴。

總結

今天我給你講解了在註冊中心實際使用過程中,服務註冊、服務反註冊、服務訂閱和服務變更的實現方式,並列舉了幾個我在服務註冊與發現的過程中遇到的典型問題。

而針對這些異常情況,我都給出了對應的解決方案,這些方案都是經過實際業務驗證的,對於大部分中小團隊在應用場景面臨的問題,應該足以應對。

思考題

你的團隊在使用註冊中心時,是否有遇到過上面這些問題呢?我給出的解決方案是否可以解決你們的問題呢?

歡迎你在留言區寫下自己的思考,與我一起討論。


分享到:


相關文章: