這篇文章主要關註服務發現,會討論基於DNS、VIP、ZooKeeper以及消息匯流排的服務發現機制,研究出在服務發現需要AP還是CP。 ...
08 | 服務發現:到底是要CP還是AP?
我們為什麼需要“服務發現”?
從高可用的角度出發,在生產環境中,服務提供方通常會以集群的方式對外提供服務,集群中的IP地址隨時可能發生變化,因此我們需要一本“通訊錄”來及時獲取對應的服務節點信息,維護“通訊錄”以及或者節點信息的過程,我們稱之為“服務發現”。
服務發現包括2個核心模塊:
- 服務註冊:在服務提供方啟動的時候,將對外暴露的介面註冊到註冊中心中,註冊中心將這個服務節點的IP和介面保存下來。
- 服務訂閱:在服務調用方啟動的時候,去註冊中心查找並訂閱服務提供方的IP,然後緩存到本地,並用於後續遠程調用。
我們為什麼不採用基於DNS的服務發現機制?
我們來看一下DNS查詢流程。
它存在的兩個主要問題:
- 如果服務節點的IP埠下線了,服務調用者能否及時摘除服務節點?
- 如果之前已經上線了一部分服務節點,這時突然對這個服務進行擴容,那麼新上線的服務節點能否及時接收到流程呢?
為什麼VIP方案也不能用於服務發現?
VIP方案如下所示。
它主要有以下幾個問題:
- 搭建負載均衡設備或者TCP/IP四層代理,需要額外成本。
- 請求流程都經過負載均衡設備,多經過一次網路傳輸,會額外浪費性能。
- 負載均衡添加節點和摘除節點,一般都需要手動添加,當大批量擴容和下線時,會有大量的人工操作和生效延遲。
- 不能支持更靈活的負載均衡策略。
基於ZooKeeper的服務發現機制的工作流程是怎樣的?
基於ZooKeeper的服務發現結構圖如下。
它的工作流程如下:
- 服務平臺管理端現在ZooKeeper中創建一個服務根路徑,在這個路徑下麵再創建服務提供方目錄和服務調用方目錄。
- 當服務提供方發起註冊時,會在服務提供方目錄中創建一個臨時節點,節點中存儲該服務提供方的註冊信息。
- 當服務調用方發起註冊時,會在服務提供方目錄中創建一個臨時節點,節點中存儲該服務提供方的註冊信息。
- 當服務提供方目錄下有節點數據發生變更時,ZooKeeper就會通知給發起訂閱的服務調用方。
基於ZooKeeper的服務發現有什麼問題?
當有超大批量的服務節點在同時發起註冊操作,ZooKeeper集群的CPU使用率會飆升,導致ZooKeeper集群無法工作。
這本身就是ZooKeeper的性能問題,當連接到ZooKeeper的節點數量特別多,對ZooKeeper的讀寫操作會特別頻繁,而且當ZooKeeper存儲的目錄達到一定數量時,ZooKeeper就會變得不穩定,CPU使用率持續升高,直到宕機。
ZooKeeper的一大特點就是強一致性,集群中的每個節點的數據每次發生變更操作時,都會通知其他節點同時執行跟新,這樣它就要求每個節點的數據能夠實時的完全一致,從而導致了ZooKeeper集群性能的下降。
基於消息匯流排的服務發現機制的工作流程是怎樣的?
基於消息匯流排的服務發現流程圖如下:
它的工作流程如下:
- 當有服務上線,註冊中心節點收到註冊請求,服務列表數據發生變化,會生成一個消息,推送給消息匯流排,每個消息都有一個整體遞增版本。
- 消息匯流排會主動推送消息到各個註冊中心,同時註冊中心也會定期拉取消息。對於獲取到消息的在消息回放模塊裡面回放只接受大於本地版本號的消息,小於本地版本號的消息直接丟棄,從而實現最終一致性。
- 消費者定於可以從註冊中心記憶體拿到指定介面的全部服務實例,並緩存到消費者的記憶體中。
- 採取推拉模式,消費者可以及時地拿到服務實例增量變化情況,並和記憶體中的混存數據進行合併。
通過消息匯流排的方式,我們就可以完成註冊中心集群間數據變更的通知,保證數據的最終一致性,並能及時地觸發註冊中心的服務下發操作。
服務發現的特性是允許我們在設計超大規模集群服務發現系統的時候,捨棄一致性,更多的考慮系統的健壯性,因此,在實際工作中,最終一致性是更為常用的策略。
作者:李潘 出處:http://wing011203.cnblogs.com/ 本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。