更新時間:2020-10-30 來源:黑馬程序員 瀏覽量:
數(shù)據(jù)發(fā)布/訂閱(Publish/Subscribe)系統(tǒng),即所謂的配置中心,顧名思義就是發(fā)布者將數(shù)據(jù)發(fā)布到ZooKeeper的一個或一系列節(jié)點上,供訂閱者進行數(shù)據(jù)訂閱,進而達到動態(tài)獲取數(shù)據(jù)的目的,實現(xiàn)配置信息的集中式管理和數(shù)據(jù)的動態(tài)更新。
發(fā)布/訂閱系統(tǒng)一般有兩種設計模式,分別是推(Push)模式和拉(Pull)模式。在推模式中,服務端主動將數(shù)據(jù)更新發(fā)送給所有訂閱的客戶端;而拉模式則是由客戶端主動發(fā)起請求來獲取最新數(shù)據(jù),通??蛻舳硕疾捎枚〞r進行輪詢拉取的方式。
ZooKeeper 采用的是推拉相結合的方式:客戶端向服務端注冊自己需要關注的節(jié)點,一旦該節(jié)點的數(shù)據(jù)發(fā)生變更,那么服務端就會向相應的客戶端發(fā)送Watcher事件通知,客戶端接收到這個消息通知之后,需要主動到服務端獲取最新的數(shù)據(jù)。
如果將配置信息存放到ZooKeeper上進行集中管理,那么通常情況下,應用在啟動的時候都會主動到ZooKeeper服務端上進行一次配置信息的獲取,同時,在指定節(jié)點上注冊一個Watcher監(jiān)聽,這樣一來,但凡配置信息發(fā)生變更,服務端都會實時通知到所有訂閱的客戶端,從而達到實時獲取最新配置信息的目的。
下面我們通過一個“配置管理”的實際案例來展示ZooKeeper在“數(shù)據(jù)發(fā)布/訂閱”場景下的使用方式。
在我們平常的應用系統(tǒng)開發(fā)中,經(jīng)常會碰到這樣的需求:系統(tǒng)中需要使用一些通用的配置信息,例如機器列表信息、運行時的開關配置、數(shù)據(jù)庫配置信息等。這些全局配置信息通常具備以下3個特性。
·數(shù)據(jù)量通常比較小。
·數(shù)據(jù)內(nèi)容在運行時會發(fā)生動態(tài)變化。
·集群中各機器共享,配置一致。
對于這類配置信息,一般的做法通常可以選擇將其存儲在本地配置文件或是內(nèi)存變量中。無論采用哪種方式,其實都可以簡單地實現(xiàn)配置管理,在集群機器規(guī)模不大、配置變更不是特別頻繁的情況下,無論剛剛提到的哪種方式,都能夠非常方便地解決配置管理的問題。但是,一旦機器規(guī)模變大,且配置信息變更越來越頻繁后,我們發(fā)現(xiàn)依靠現(xiàn)有的這兩種方式解決配置管理就變得越來越困難了。我們既希望能夠快速地做到全局配置信息的變更,同時希望變更成本足夠小,因此我們必須尋求一種更為分布式化的解決方案
接下來我們就以一個“數(shù)據(jù)庫切換”的應用場景展開,看看如何使用ZooKeeper來實現(xiàn)配置管理:
·配置存儲
在進行配置管理之前,首先我們需要將初始化配置信息存儲到Zookeeper上去,一般情況下,我們可以在Zookeeper上選取一個數(shù)據(jù)節(jié)點用于配置信息的存儲,例如:/app1/database_config。
配置管理的zookeeper節(jié)點示意圖
我們將需要管理的配置信息寫入到該數(shù)據(jù)節(jié)點中去,例如:
#數(shù)據(jù)庫配置信息 #DBCP dbcp.driverClassName=com.mysql.jdbc.Driver dbcp.dbJDBCUrl=jdbc:mysql://127.0.0.1:3306/lagou-test dbcp.username=zm dbcp.password=1234 dbcp.maxActive=30 dbcp.maxIdle=10
配置獲取
集群中每臺機器在啟動初始化階段,首先會從上面提到的ZooKeeper配置節(jié)點上讀取數(shù)據(jù)庫信息,同時,客戶端還需要在該配置節(jié)點上注冊一個數(shù)據(jù)變更的
Watcher監(jiān)聽,一旦發(fā)生節(jié)點數(shù)據(jù)變更,所有訂閱的客戶端都能夠獲取到數(shù)據(jù)變更通知。
配置變更
在系統(tǒng)運行過程中,可能會出現(xiàn)需要進行數(shù)據(jù)庫切換的情況,這個時候就需要進行配置變更。借助ZooKeeper,我們只需要對ZooKeeper上配置節(jié)點的內(nèi)容進行更新,ZooKeeper就能夠幫我們將數(shù)據(jù)變更的通知發(fā)送到各個客戶端,每個客戶端在接收到這個變更通知后,就可以重新進行最新數(shù)據(jù)的獲取。
猜你喜歡: