ZooKeeper實現服務注冊中心


 

ZooKeeper實現服務注冊中心

ZooKeeper官網地址:https://zookeeper.apache.org/

一、Zookeeper概述

 ZooKeeper是一個開源的、分布式的應用程序協調服務。它提供的功能包括:命名服務、配置管理、集群管理、分布式鎖、負載均衡、分布式隊列等。

(1)命名服務。可以簡單理解為電話簿。電話號碼不好記,但是人名好記,要打誰的電話,直接查人名就好了。分布式環境下,經常需要對應用/服務進行統一命名,便於識別不同的服務。類似於域名與IP之間的對應關系,域名容易記住。ZooKeeper通過名稱來獲取資源或服務的地址、提供者等信息。

(2)配置管理。分布式系統都有大量的服務器,比如在搭建Hadoop的HDFS的時候,需要在一台Master主機器上配置好HDFS需要的各種配置文件,然后通過scp命令把這些配置文件復制到其他節點上,這樣各個機器拿到的配置信息是一致的,才能成功運行HDFS服務。ZooKeeper提供了這樣的一種服務:一種集中管理配置的方法,我們在這個集中的地方修改了配置,所有對這個配置感興趣的服務都可以獲得變更。這樣就省去手動復制配置,還保證了可靠性和一致性。

(3)集群管理。集群管理包含兩點:是否有機器退出和加入、選舉Master。在分布式集群中,經常會由於各種原因,比如硬件故障、軟件故障、網絡問題等,有些新的節點會加入進來,也有老的節點會退出集群。這個時候,集群中有些機器(比如Master節點)需要感知到這種變化,然后根據這種變化做出對應的決策。ZooKeeper集群管理就是感知變化,做出對應的策略。

(4)分布式鎖。ZooKeeper的一致性文件系統使得鎖的問題變得容易。鎖服務可以分為兩類,一類是保持獨占;另一類是控制時序。單機程序的各個進程需要對互斥資源進行訪問時需要加鎖,分布式程序分布在各個主機上的進程對互斥資源進行訪問時也需要加鎖。

 

二、ZooKeeper的原理

ZooKeeper一個常用的使用場景是擔任服務生產者和服務消費者的注冊中心,這也是接下來的章節中會使用到的。服務生產者將自己提供的服務注冊到ZooKeeper中心,服務消費者在進行服務調用的時候先到ZooKeeper中查找服務,獲取服務生產者的詳細信息之后,再去調用服務生產者的內容與數據,具體如圖7-2所示

 

三、ZooKeeper集群總體架構

ZooKeeper集群中有4種角色,如表7-1所示。

  ZooKeeper集群由一組Server節點組成,這一組Server節點中存在一個角色為Leader的節點,其他節點為Follower或Observer。ZooKeeper集群總體架構如圖7-4所示。

 

 ZooKeeper擁有一個層次的命名空間,這和標准的文件系統非常相似。ZooKeeper中的每個節點被稱為Znode,每個節點可以擁有子節點。ZooKeeper數據模型架構如圖7-5所示。

ZooKeeper命名空間中的Znode兼具文件和目錄兩種特點,既可以像文件一樣維護數據、元信息、ACL、時間戳等數據結構,又可以像目錄一樣作為路徑標識的一部分。每個Znode由以下3部分組成。
stat:存儲狀態信息,用於描述該Znode的版本、權限等信息。
data:存儲與該Znode關聯的數據。
children:存儲該Znode下的子節點。


ZooKeeper雖然可以關聯一些數據,但並沒有被設計為常規的關系型數據庫或者大數據存儲,相反的是,Znode用來管理調度數據,比如分布式應用中的配置文件信息、狀態信息、匯集位置等。ZooKeeper規定節點的數據大小不能超過1MB,但在實際使用中Znode的數據量應該盡可能小,因為數據量過大會導致ZooKeeper性能明顯下降。
Znode有以下4種類型:
PERSISTENT:持久節點。ZooKeeper客戶端與ZooKeeper服務器端斷開連接后,該節點依舊存在。

PERSISTENT_SEQUENTIAL:持久順序節點。ZooKeeper客戶端與ZooKeeper服務器端斷開連接后,該節點依舊存在,並且ZooKeeper給該節點名稱進行順序編號。
EPHEMERAL:臨時節點。和持久節點不同的是,臨時節點的生命周期和客戶端會話綁定。如果客戶端會話失效,那么這個節點會被自動清除。在臨時節點下不能創建子節點。
EPHEMERAL_SEQUENTIAL:臨時順序節點。臨時順序節點的生命周期和客戶端會話綁定。如果客戶端會話失效,那么這個節點會被自動清除。創建的節點會自動加上編號。

 

四、命令行客戶端zkCli.sh

ZooKeeper為我們提供了一系列的腳本程序,放置在bin目錄下,具體如下:
zkCleanup.sh:用於清理ZooKeeper的歷史數據,包括事務日志文件與快照數據文件。
zkCli.sh:用於連接ZooKeeper服務器的命令行客戶端。

zkEnv.sh:用於設置ZooKeeper的環境變量。
zkServer.sh:用於啟動ZooKeeper服務器。
可以使用zkCli.sh命令行客戶端來連接與操作ZooKeeper服務器,這是本節的重點。下面我們來看一些具體實例。
(1)連接ZooKeeper服務器

  在bin目錄下執行zkCli.sh腳本

(2)連接遠程ZooKeeper服務器

     命令格式:sh zkCli.sh -service <ip>:<port>。
(3)列出子節點

    命令格式:ls path [watch]。

(4)判斷節點是否存在

### 使用stat 命令判斷 /ay 節點是否存在,很明顯,/ay節點不存在
[zk: localhost:2181(CONNECTED) 6] stat /ay
Node does not exist: /ay

(5)創建節點命令格式:create [-s] [-e] path data acl。
[-s]選項:用於指定該節點是否為順序節點。
[-e]選擇:用於指定該節點是否為臨時節點。

(6)獲取節點數據

    命令格式:get path [watch]。

 (7)更新節點數據

   命令格式:set path data [version]。

(8)刪除節點

  命令格式:delete path [version]

五、ZkClient連接ZooKeeper

  ZkClient是基於ZooKeeper原生的Java API開發的一個易用性更好的客戶端,實現了Session超時自動重連、Watcher反復注冊等功能,規避了ZooKeeper原生的Java API使用不方便的問題。接下來我們先簡單了解ZkClient提供的API。

(1)創建會話連接API,代碼如下所示:

serverstring:格式為host1:port1,host2:port2組成的字符串。
connectionTimeout:創建連接的超時時間,單位為ms。
sessionTimeout:會話超時時間,單位為ms。
zkSerializer:自定義zk節點存儲數據的序列化方式。對於zkSerializer,ZkClient默認使用Java自帶的序列化方式。
IZkConnection:接口自定義實現。對於IZkConnection接口,ZkClient默認提供了兩種實現,分別是zkConnection和InMemoryConnection。一般使用ZkConnection即可滿足絕大多數使用場景的需要。

(2)創建節點API,代碼如下所示:

(3)刪除節點主要API,代碼如下所示:

(4)讀取節點主要API,代碼如下所示:

(5)更新節點主要API,代碼如下所示:

六、Spring Boot項目引入ZKClient連接ZooKeeper服務器

  了解ZkClient提供的CRUD接口,,接下來我們學習如何使用ZkClient連接ZooKeeper服務器

  1、在pom.xml文件中引入ZkClient的Maven依賴

   

 2、我們使用ZkClient對節點進行增、刪、改、查等操作

   

七、ZooKeeper實現服務注冊與發現

ZooKeeper充當一個服務注冊表(Service Registry),讓多個服務提供者形成一個集群,讓服務消費者通過服務注冊表獲取具體的服務訪問地址(IP+端口)去訪問具體的服務提供者,如圖7-6所示。

ZooKeeper類似於分布式文件系統,當服務提供者部署后,將自己的服務注冊到ZooKeeper的某一路徑上:/{service}/{version}/{ip:port},比如我們的ProductService部署到兩台機器上,ZooKeeper上就會創建兩條目錄:/ProductService/1.0.0/100.19.20.01:16888和/ProductService/1.0.0/100.19.20.02:16888。

再來看一張更容易理解的圖,具體如圖7-7所示。

 

(1)ZooKeeper客戶端通過創建ZooKeeper的一個實例對象連接ZooKeeper服務器,調用該類的接口與服務器交互。
(2)根據服務提供者發布的服務列表循環調用create接口,創建目錄節點,同時將服務屬性(服務名稱和IP)寫入目錄節點的內容中。
(3)服務消費者同樣通過ZooKeeper客戶端創建ZooKeeper的一個實例對象,連接ZooKeeper服務器,調用該類的接口與服務器交互。
(4)服務消費者在第一次調用服務時,會通過注冊中心找到相應的服務的IP地址列表,並緩存到本地,以供后續使用。當消費者調用服務時,不會再去請求注冊中心,而是直接通過負載均衡算法從IP列表中獲取一個服務提供者的服務器調用服務。
(5)當服務提供者的某台服務器宕機或下線時,相應的IP會被移除。同時,注冊中心會將新的服務IP地址列表發送給服務消費者機器,緩存在消費者本機。
(6)當某個服務的所有服務器都下線了,這個服務也就下線了。
(7)同樣,當服務提供者的某台服務器上線時,注冊中心會將新的服務IP地址列表發送給服務消費者機器,緩存在消費者本機。

(8)服務提供方可以根據服務消費者的數量來作為服務下線的依據。
ZooKeeper提供了“心跳檢測”功能,它會定時向各個服務提供者發送請求,實際上建立的是一個Socket長連接,如果長期沒有響應,服務中心就認為該服務提供者已經“掛了”,並將其剔除,比如10.10.10.02這台機器如果宕機了,ZooKeeper上的路徑就只剩/ProductService/1.0.0/10.10.10.01:16888。

服務消費者會去監聽相應路徑(/ProductService/1.0.0),一旦路徑上的數據有任何變化(增加或減少),ZooKeeper都會通知服務消費方,服務提供者地址列表已經發生改變,從而進行更新。更為重要的是ZooKeeper與生俱來的容錯容災能力(比如Leader選舉),可以確保服務注冊表的高可用性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM