国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù)

這篇具有很好參考價值的文章主要介紹了分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、Zookeeper概述

1.1?集中式和分布式

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

單機架構(gòu)

一個系統(tǒng)業(yè)務(wù)量很小的時候所有的代碼都放在一個項目中就好了,然后這個項目部署在一臺服務(wù)器上,整個項目所有的服務(wù)都由這臺服務(wù)器提供。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

缺點:

  • 服務(wù)性能存在瓶頸,用戶增長的時候性能下降等。
  • 不可伸縮性
  • 代碼量龐大,系統(tǒng)臃腫,牽一發(fā)動全身
  • 單點故障問題

集群架構(gòu)

單機處理到達瓶頸的時候,你就把單機復制幾份,這樣就構(gòu)成了一個集群。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

集群存在的問題:

當你的業(yè)務(wù)發(fā)展到一定程度的時候,你會發(fā)現(xiàn)一個問題無論怎么增加節(jié)點,貌似整個集群性能的提升效果并不明顯了。這時候,你就需要使用分布式架構(gòu)了。

分布式架構(gòu)

分布式架構(gòu)就是將一個完整的系統(tǒng),按照業(yè)務(wù)功能,拆分成一個個獨立的子系統(tǒng),在分布式結(jié)構(gòu)中,每個子系統(tǒng)就被稱為“服務(wù)”。這些子系統(tǒng)能夠獨立運行在web容器中,它們之間通過RPC方式通信(遠程調(diào)用)。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

分布式的優(yōu)勢:

  1. 系統(tǒng)之間的耦合度大大降低,可以獨立開發(fā)、獨立部署、獨立測試,系統(tǒng)與系統(tǒng)之間的邊界非常明確排錯也變得相當容易,開發(fā)效率大大提升。
  2. 系統(tǒng)之間的耦合度降低,從而系統(tǒng)更易于擴展。我們可以針對性地擴展某些服務(wù)。
  3. 服務(wù)的復用性更高。比如,當我們將用戶系統(tǒng)作為單獨的服務(wù)后,該公司所有的產(chǎn)品都可以使用該系統(tǒng)作為用戶系統(tǒng),無需重復開發(fā)。

?三者區(qū)別

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

總結(jié):

將一套系統(tǒng)拆分成不同子系統(tǒng)部署在不同服務(wù)器上(這叫分布式),然后部署多個相同的子系統(tǒng)在不同的服務(wù)器上(這叫集群)。

集群:多個人在一起作同樣的事 。

分布式?:多個人在一起作不同的事 。

?1.2?CAP定理

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?分布式系統(tǒng)正變得越來越重要,大型網(wǎng)站幾乎都是分布式的。分布式系統(tǒng)的最大難點,就是各個節(jié)點的狀態(tài)如何同步。CAP 定理是這方面的基本定理,也是理解分布式系統(tǒng)的起點。說白了,就是要使各個模塊的狀態(tài)、數(shù)據(jù)共享,保持數(shù)據(jù)一致。

分布式系統(tǒng)的三個指標

  • Consistency(一致性)
  • Availability (可用性)
  • Partition tolerance (分區(qū)容錯性)

分區(qū)容錯性

大多數(shù)分布式系統(tǒng)都分布在多個子網(wǎng)絡(luò)。每個子網(wǎng)絡(luò)就叫做一個區(qū)。分區(qū)容錯的意思是,區(qū)間通信可能失敗。比如,一臺服務(wù)器放在中國,另一臺服務(wù)器放在美國,這就是兩個區(qū),它們之間可能無法通信。

結(jié)論:

分區(qū)容錯無法避免,因此可以認為 CAP 的 P 總是成立。CAP 定理告訴我們,剩下的 C 和 A 無法同時做到。

一致性

寫操作之后的讀操作,必須返回該值。舉例來說,某條記錄是 v0,用戶向 G1 發(fā)起一個寫操作,將其改為 v1。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

接下來,用戶的讀操作就會得到 v1。這就叫一致性。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

問題是,用戶有可能向 G2 發(fā)起讀操作,由于 G2 的值沒有發(fā)生變化,因此返回的是 v0。G1 和 G2 讀操作的結(jié)果不一致,這就不滿足一致性了。?

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?為了讓 G2 也能變?yōu)?v1,就要在 G1 寫操作的時候,讓 G1 向 G2 發(fā)送一條消息,要求 G2 也改成 v1。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?可用性

只要收到用戶的請求,服務(wù)器就必須給出回應(yīng).

解釋:

用戶可以選擇向 G1 或 G2 發(fā)起讀操作。不管是哪臺服務(wù)器,只要收到請求,就必須告訴用戶,到底是 v0 還是 v1,否則就不滿足可用性。

一致性和可用性的矛盾

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

解釋:

如果保證 G2 的一致性,那么 G1 必須在寫操作時,鎖定 G2 的讀操作和寫操作。只有數(shù)據(jù)同步后,才能重新開放讀寫。鎖定期間,G2 不能讀寫,沒有可用性不。

一致性和可用性如何選擇?

  • 一致性(CP)

特別是涉及到重要的數(shù)據(jù),就比如錢,商品數(shù)量,商品價格。

  • 可用性? (AP)

網(wǎng)頁的更新不是特別強調(diào)一致性,短時期內(nèi),一些用戶拿到老版本,另一些用戶拿到新版本,問題不會特別大。

1.3?什么是Zookeeper

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?分布式架構(gòu)

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

多個節(jié)點協(xié)同問題:

  1. 每天的定時任務(wù)由誰哪個節(jié)點來執(zhí)行?
  2. RPC調(diào)用時的服務(wù)發(fā)現(xiàn)?
  3. 如何保證并發(fā)請求的冪等

這些問題可以統(tǒng)一歸納為多節(jié)點協(xié)調(diào)問題,如果靠節(jié)點自身進行協(xié)調(diào)這是非常不可靠的,性能上也不可取。必須由一個獨立的服務(wù)(zooKeeper)做協(xié)調(diào)工作,它必須可靠,而且保證性能。

一個應(yīng)用程序,涉及多個進程協(xié)作時,`業(yè)務(wù)邏輯代碼中混雜有大量復雜的進程協(xié)作邏輯。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

上述多進程協(xié)作邏輯,有 2 個特點:

  • 處理復雜
  • 處理邏輯可重用

?因此,考慮將多進程協(xié)作的共性問題拎出,作為基礎(chǔ)設(shè)施,讓 RD 更加專注業(yè)務(wù)邏輯開發(fā),即:

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?Zookeeper從何而來?

?ZooKeeper最早起源于雅虎研究院的一個研究小組。在當時,研究人員發(fā)現(xiàn),在雅虎內(nèi)部很多大型系統(tǒng)基本都需要依賴一個類似的系統(tǒng)來進行分布式協(xié)調(diào),但是這些系統(tǒng)往往都存在分布式單點問題。

解決:

雅虎的開發(fā)人員就試圖開發(fā)一個通用的無單點問題的分布式協(xié)調(diào)框架,以便讓開發(fā)人員將精力集中在處理業(yè)務(wù)邏輯上。

Zookeeper介紹

ZooKeeper是一個開放源代碼的分布式協(xié)調(diào)服務(wù)。ZooKeeper的設(shè)計目標是將那些復雜且容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并以一系列簡單易用的接口提供給用戶使用。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

說明:

Zookeeper顧名思義就是動物園管理員。 因為Hadoop生態(tài)各個項目都是動物得圖標。 所以很符合管理員得形象。

?1.3?應(yīng)用場景

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

數(shù)據(jù)發(fā)布/訂閱

數(shù)據(jù)發(fā)布/訂閱的一個常見的場景是配置中心,發(fā)布者把數(shù)據(jù)發(fā)布到 ZooKeeper 的一個或一系列的節(jié)點上,供訂閱者進行數(shù)據(jù)訂閱,達到動態(tài)獲取數(shù)據(jù)的目的。例如我們可以將A\B\C三個應(yīng)用的數(shù)據(jù)庫連接信息寫到公共的服務(wù)中,當數(shù)據(jù)庫異常時可以快速切換到其他正常的數(shù)據(jù)庫。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

ZooKeeper 采用的是推拉結(jié)合的方式。

  1. 推: 服務(wù)端會推給注冊了監(jiān)控節(jié)點的客戶端 Wathcer 事件通知
  2. 拉: 客戶端獲得通知后,然后主動到服務(wù)端拉取最新的數(shù)據(jù)

具體流程:

  1. 把配置信息寫到一個 Znode 上,例如?/DBConfiguration
  2. 客戶端啟動初始化階段讀取服務(wù)端節(jié)點的數(shù)據(jù),并且注冊一個數(shù)據(jù)變更的 Watcher
  3. 配置變更只需要對 Znode 數(shù)據(jù)進行 set 操作,數(shù)據(jù)變更的通知會發(fā)送到客戶端,客戶端重新獲取新數(shù)據(jù),完成配置動態(tài)修改

負載均衡

負載均衡是一種手段,用來把對某種資源的訪問分攤給不同的設(shè)備,從而減輕單點的壓力。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

實現(xiàn)的思路:
  1. 首先建立 Servers 節(jié)點,并建立監(jiān)聽器監(jiān)視 Servers 子節(jié)點的狀態(tài)(用于在服務(wù)器增添時及時同步當前集群中服務(wù)器列表)
  2. 在每個服務(wù)器啟動時,在 Servers 節(jié)點下建立臨時子節(jié)點?Worker Server,并在對應(yīng)的字節(jié)點下存入服務(wù)器的相關(guān)信息,包括服務(wù)的地址,IP,端口等等
  3. 可以自定義一個負載均衡算法,在每個請求過來時從 ZooKeeper 服務(wù)器中獲取當前集群服務(wù)器列表,根據(jù)算法選出其中一個服務(wù)器來處理請求

命名服務(wù)

命名服務(wù)就是提供名稱的服務(wù)。ZooKeeper 的命名服務(wù)有兩個應(yīng)用方面。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

功能:

  1. 提供類 JNDI 功能,可以把系統(tǒng)中各種服務(wù)的名稱、地址以及目錄信息存放在 ZooKeeper,需要的時候去 ZooKeeper 中讀取
  2. 制作分布式的序列號生成器.

分布式協(xié)調(diào)/通知

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?總結(jié):

zookeeper是一個文件系統(tǒng)加監(jiān)聽機制,很牛逼就完了!

?1.4?為什么要選擇Zookeeper?

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

隨著分布式架構(gòu)的出現(xiàn),越來越多的分布式應(yīng)用會面臨數(shù)據(jù)一致性問題。很遺憾的是,在解決分布式數(shù)據(jù)一致性上,除了ZooKeeper之外,目前還沒有一個成熟穩(wěn)定且被大規(guī)模應(yīng)用的解決方案。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

主要:

ZooKeeper無論從易用性還是穩(wěn)定性上來說,都已經(jīng)達到了一個工業(yè)級產(chǎn)品的標準。ZooKeeper是免費的,你無須為它支付任何費用。這點對于一個小型公司,尤其是初創(chuàng)團隊來說,無疑是非常重要的。

?廣泛應(yīng)用

最后,ZooKeeper已經(jīng)得到了廣泛的應(yīng)用。諸如Hadoop、HBase、Storm、kafka等越來越多的大型分布式項目都將Zookeeper作為核心組件。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

1.5?基本概念

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

集群角色

通常在分布式系統(tǒng)中,構(gòu)成一個集群的每一臺機器都有自己的角色,最典型的集群模式就是Master/Slave模式(主備模式)。在這種模式中,我們把能夠處理所有寫操作的機器稱為Master機器,把所有通過異步復制方式獲取最新數(shù)據(jù),并提供讀服務(wù)的機器稱為Slave機器。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

概念顛覆:

而在ZooKeeper中,這些概念被顛覆了。它沒有沿用傳統(tǒng)的MasterlSlave概念,而是引入了Leader、Follower和 Observer三種角色。

?數(shù)據(jù)節(jié)點(znode)

在談到分布式的時候,我們通常說的“節(jié)點”是指組成集群的每一臺機器。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

在ZooKeeper中節(jié)點分為兩類

  • 第一類同樣是指構(gòu)成集群的機器,我們稱之為機器節(jié)點
  • 第二類則是指數(shù)據(jù)模型中的數(shù)據(jù)單元,我們稱之為數(shù)據(jù)節(jié)點——ZNode。

ZooKeeper將所有數(shù)據(jù)存儲在內(nèi)存中,數(shù)據(jù)模型是一棵樹。

Watcher監(jiān)聽機制

Watcher(事件監(jiān)聽器),是ZooKeeper 中的一個很重要的特性。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

注意:

ZooKeeper 允許用戶在指定節(jié)點上注冊一些Watcher,并且在一些特定事件觸發(fā)的時候,ZooKeeper 服務(wù)端會將事件通知到感興趣的客戶端上去,該機制是ZooKeeper實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。

ACL權(quán)限控制

ZooKeeper 采用ACL (Access Control Lists)策略來進行權(quán)限控制,類似于UNIX文件系統(tǒng)的權(quán)限控制。ZooKeeper定義了如下5種權(quán)限。

  • CREATE:創(chuàng)建子節(jié)點的權(quán)限
  • READ:獲取節(jié)點數(shù)據(jù)和子節(jié)點列表的權(quán)限
  • WRITE:更新節(jié)點數(shù)據(jù)的權(quán)限
  • DELETE:刪除子節(jié)點的權(quán)限
  • ADMIN:設(shè)置節(jié)點ACL的權(quán)限

注意:

create和delete這兩種權(quán)限都是針對子節(jié)點的權(quán)限控制。

二、Zookeeper部署運行

2.1?偽集群安裝

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

偽集群模式適合在開發(fā)和測試的環(huán)境下使用。?

下載Zookeeper,并上傳到Linux

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

注意:需要配置JDK環(huán)境支持。

解壓zookeeper

tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz -C /usr/local

#修改名稱
mv apache-zookeeper-3.7.0-bin   zookeeper

修改配置文件

進入zookeeper的安裝目錄的conf目錄

cd conf

#修改樣式文件名稱
mv zoo_sample.cfg zoo.cfg

修改zoo.cfg,配置zookeeper數(shù)據(jù)存放位置和日志存放位置。?

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

創(chuàng)建數(shù)據(jù)持久化目錄

mkdir /usr/local/zookeeper/zkdata
mkdir /usr/local/zookeeper/zklogs

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?啟動zookeeper服務(wù)

[root@localhost zookeeper]# ./bin/zkServer.sh start

查看Zookeeper運行狀態(tài)

[root@localhost zookeeper]# ./bin/zkServer.sh status

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

關(guān)閉zookeeper?

[root@localhost bin]# ./zkServer.sh stop

?2.2集群安裝

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?1.環(huán)境準備

注意在集群部署之前先刪除zkdata和zklogs目錄下的文件,這兩個目錄下的文件是在偽集群搭建的時候產(chǎn)生的。

服務(wù)器(純凈)? 192.168.66.100
服務(wù)器(zk-1)? 192.168.66.101
服務(wù)器(zk-2)?192.168.66.102

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?2.將純凈中的jdk傳到zk-1和zk-2中

# 將純凈虛擬機的jdk傳遞到zk-1虛擬機,文件的位置和純凈的相同
scp -r jdk1.8/  192.168.66.101:$PWD

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?3.分別為zk-1和zk-2兩臺虛擬機配置JDK環(huán)境。


#進入配置文件
vim /etc/profile

#在配置文件添加如下配置
export JAVA_HOME=/usr/local/jdk1.8
export PATH=$PATH:$JAVA_HOME/bin


#使配置文件生效
source /etc/profile


#查看jdk是否配置成功
Java -version

4.修改純凈虛擬機的zookeeper的配置文件zoo.cfg

#進入配置文件
vim zoo.cfg


#在配置文件中添加如下配置
dataDir=/usr/local/zookeeper/zkdata
dataLogDir=/usr/local/zookeeper/zklogs

clientPort=2181
server.1=192.168.66.100:2888:3888
server.2=192.168.66.101:2888:3888
server.3=192.168.66.102:2888:3888

5.將純凈中的zookeeper分發(fā)到zk-1和zk-2兩臺虛擬機。?

scp -r zookeeper/  192.168.66.101:$PWD
scp -r zookeeper/  192.168.66.102:$PWD

6.為三個虛擬機中的zookeeper分別設(shè)置ID

#在純凈虛擬機中的zookeeper下的zkdata目錄下使用:
echo 1 > myid
#在zk-1虛擬機中的zookeeper下的zkdata目錄下使用:
echo 2 > myid
#在zk-2虛擬機中的zookeeper下的zkdata目錄下使用:
echo 3 > myid

7.開啟三個虛擬機的zookeeper服務(wù)

#先將三個虛擬機的防火墻關(guān)了
service firewalld stop

#開啟zookeeper服務(wù)(因為沒有配置環(huán)境變量,因此在開啟服務(wù)的時候要在bin下開啟)
[root@localhost bin]# ./zkServer.sh start

#查看服務(wù)狀態(tài)
[root@localhost bin]# ./zkServer.sh status

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

注意:

啟動后,用jps應(yīng)該能看到一個進程:QuorumPeerMain。光有進程不代表zk已經(jīng)正常服務(wù),需要用命令檢查狀態(tài):bin/zkServer.sh status 能看到角色模式:為leader或follower,即正常了。

2.3?服務(wù)管理

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

腳本 說明
zkCleanup 清理Zookeeper歷史數(shù)據(jù),包括事務(wù)日志文件和快照數(shù)據(jù)文件
zkCli Zookeeper的簡易客戶端
zkEnv 設(shè)置Zookeeper的環(huán)境變量
zkServer Zookeeper服務(wù)器的啟動、停止和重啟腳本

配置環(huán)境變量(三臺虛擬機都需要配置)

#打開配置文件
vim /etc/profile

#在配置文件中添加如下配置
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin

#配置生效
source /etc/profile

這樣在任何一個文件下使用zkServer.sh start 都能啟動zookeeper服務(wù)。

創(chuàng)建一鍵啟動/一鍵停止腳本

如果集群中存在很多的zookeeper服務(wù)的話,一個個開啟或者是關(guān)閉的話無疑是非常麻煩的事情,因此我們可以使用一個腳本來管理全部的服務(wù)的開啟和關(guān)閉。

#在zookeeper的bin下創(chuàng)建可執(zhí)行文件
vim zkStart-all.sh


#為文件添加權(quán)限
chmod +x zkStart-all.sh
#在配置文件添加如下配置

if [ $# -ne 1 ];then
   echo "無效參數(shù),用法為: $1  {start|stop|restart|status}"
   exit
fi
#遍歷所有節(jié)點
for host in  192.168.66.101 192.168.66.102 192.168.66.103
do
  echo "========== $host 正在  $1 ========= " 
  #發(fā)送命令給目標機器
  ssh $host "source /etc/profile; /usr/local/zookeeper/bin/zkServer.sh $1"


done
#啟動腳本
./zkStart-all.sh  start


#查看集群中各個虛擬機的狀態(tài)
./zkStart-all.sh  status


#關(guān)閉全部zookeeper服務(wù)
./zkStart-all.sh  stop

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?三、Zookeeper系統(tǒng)模型

?3.1 數(shù)據(jù)模型

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

在Zookeeper中,可以說 Zookeeper中的所有存儲的數(shù)據(jù)是由znode組成的,節(jié)點也稱為 znode,并以 key/value 形式存儲數(shù)據(jù)。

?樹

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

介紹:

整體結(jié)構(gòu)類似于 linux 文件系統(tǒng)的模式以樹形結(jié)構(gòu)存儲。其中根路徑以?/?開頭。

保存數(shù)據(jù)

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

注意:

以 key/value 形式存儲數(shù)據(jù)。key就是znode的節(jié)點路徑,比如 /java , /server。value就是spring和192.168.66.100

3.2 節(jié)點類型及特性

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

ZooKeeper 節(jié)點是有生命周期的,這取決于節(jié)點的類型。節(jié)點類型可以分為持久節(jié)點、臨時節(jié)點,以及時序節(jié)點,具體在節(jié)點創(chuàng)建過程中,一般是組合使用,可以生成以下 4 種節(jié)點類型:

持久節(jié)點

持久節(jié)點是zookeeper中最常見的一種節(jié)點類型。所謂持久節(jié)點,是指改數(shù)據(jù)節(jié)點被創(chuàng)建后,就會一直存在與zookeeper服務(wù)器上,直到有刪除操作來主動清除這個節(jié)點。

/java ?spring
/zk? zk-1

持久順序節(jié)點

這類節(jié)點的基本特性和上面的節(jié)點類型是一致的。額外的特性是,在ZK中,每個父節(jié)點會為他的第一級子節(jié)點維護一份時序,會記錄每個子節(jié)點創(chuàng)建的先后順序。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

臨時節(jié)點

  • 從名稱上可以看出該節(jié)點的一個最重要的特性就是臨時性。
  • 所謂臨時性是指,如果將節(jié)點創(chuàng)建為臨時節(jié)點,那么該節(jié)點數(shù)據(jù)不會一直存儲在 ZooKeeper 服務(wù)器上。

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

區(qū)別:

和持久節(jié)點不同的是,臨時節(jié)點的生命周期和客戶端會話綁定。也就是說,如果客戶端會話失效,那么這個節(jié)點就會自動被清除掉。注意,這里提到的是會話失效,而非連接斷開。另外,在臨時節(jié)點下面不能創(chuàng)建子節(jié)點。

臨時順序節(jié)點

臨時順序節(jié)點的基本特性和臨時節(jié)點是一致的,同樣是在臨時節(jié)點的基礎(chǔ)上,添加了順序的特性。

3.3?客戶端命令行

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

#開啟zookeeper集群
zkStart-all.sh start


#進入純凈虛擬機的zookeeper文件系統(tǒng)
zkCli.sh

#在根路徑下創(chuàng)建持久節(jié)點java,節(jié)點存放的數(shù)據(jù)是spring
[zk: localhost:2181(CONNECTED) 0] create /java spring


#查看根目錄下有哪些節(jié)點
[zk: localhost:2181(CONNECTED) 1] ls /
[java, zookeeper]


#獲取Java節(jié)點的值
[zk: localhost:2181(CONNECTED) 2] get /java
spring


#修改Java節(jié)點的值為springmvc
[zk: localhost:2181(CONNECTED) 3] set /java  springmvc


#刪除Java節(jié)點
[zk: localhost:2181(CONNECTED) 5] delete /java

創(chuàng)建臨時節(jié)點:create -e? /java? ?spring

創(chuàng)建持久型順序節(jié)點:create -s? /java? spring

3.4?節(jié)點信息

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

節(jié)點的狀態(tài)結(jié)構(gòu)

每個節(jié)點都有屬于自己的狀態(tài)信息,這就很像每個人的身份信息一樣。

#查看Java節(jié)點的信息
[zk: localhost:2181(CONNECTED) 8] stat /java
cZxid = 0x500000005
ctime = Wed Jun 28 01:58:53 CST 2023
mZxid = 0x500000005
mtime = Wed Jun 28 01:58:53 CST 2023
pZxid = 0x500000005
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?3.5?Watcher監(jiān)聽機制

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

ZooKeeper 提供了分布式數(shù)據(jù)的發(fā)布/訂閱功能。一個典型的發(fā)布/訂閱模型系統(tǒng)定義了一種一對多的訂閱關(guān)系,能夠讓多個訂閱者同時監(jiān)聽某一個主題對象,當這個主題對象自身狀態(tài)變化時,會通知所有訂閱者,使它們能夠做出相應(yīng)的處理。?

注意:

在ZooKeeper中,引入了Watcher機制來實現(xiàn)這種分布式的通知功能。ZooKeeper 允許客戶端向服務(wù)端注冊一個 Watcher 監(jiān)聽,當服務(wù)端的一些指定事件觸發(fā)了這個Watcher,那么就會向指定客戶端發(fā)送一個事件通知來實現(xiàn)分布式的通知功能。

監(jiān)聽節(jié)點變化
#純凈客戶端監(jiān)聽Java節(jié)點的變化
ls -w /java


#在zk-1客戶端創(chuàng)建/java/spring節(jié)點
[zk: localhost:2181(CONNECTED) 1] create /java/spring   spirngmvc
Created /java/spring


#純凈客戶端監(jiān)聽到了Java節(jié)點的變化
[zk: localhost:2181(CONNECTED) 11] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/java

注意:

命令如果使用 -w ,那么監(jiān)聽的是節(jié)點的變化,而不是值的變化。

監(jiān)聽節(jié)點的值的變化
#純凈客戶端監(jiān)聽節(jié)點/java/spring的值
get -w /java/spring


#zk-1客戶端修改/java/spring節(jié)點的值
[zk: localhost:2181(CONNECTED) 2] set /java/spring  mybatis


#純凈客戶端監(jiān)聽到節(jié)點值的變化
[zk: localhost:2181(CONNECTED) 2] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/java/spring

注意:

watch監(jiān)聽機制只能夠使用一次,如果下次想要使用,必須重新監(jiān)聽,就比如ls path watch命令,只能監(jiān)聽節(jié)點路徑的改變一次,如果還想監(jiān)聽,那么需要再執(zhí)行一次ls path watch命令。

3.6?權(quán)限控制ACL

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?在ZooKeeper的實際使用中,我們的做法往往是搭建一個共用的ZooKeeper集群,統(tǒng)一為若干個應(yīng)用提供服務(wù)。在這種情況下,不同的應(yīng)用之間往往是不會存在共享數(shù)據(jù)的使用場景的,因此需要解決不同應(yīng)用之間的權(quán)限問題。

注意:?

  1. ZooKeeper的權(quán)限控制是基于每個znode節(jié)點的,需要對每個節(jié)點設(shè)置權(quán)限
  2. 每個znode支持設(shè)置多種權(quán)限控制方案和多個權(quán)限
  3. 子節(jié)點不會繼承父節(jié)點的權(quán)限,客戶端無權(quán)訪問某節(jié)點,但可能可以訪問它的子節(jié)點

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

權(quán)限模式schema

ZooKeeper內(nèi)置了一些權(quán)限控制方案,可以用以下方案為每個節(jié)點設(shè)置權(quán)限:

方案 描述
world 只有一個用戶:anyone,代表所有人(默認)
ip 使用IP地址認證
auth 使用已添加認證的用戶認證
digest 使用“用戶名:密碼”方式認證

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

授權(quán)對象ID

授權(quán)對象ID是指,權(quán)限賦予的用戶或者一個實體,例如:IP 地址或者機器。授權(quán)模式 schema 與 授權(quán)對象 ID 之間關(guān)系:

權(quán)限模式 授權(quán)對象
IP 通常是一個IP地址或是IP段,例如“192.168.66.101”
Digest 自定義,通常是“username:BASE64(SHA-1(username:password))”
World 只有一個ID:"anyone"
Super 與Digest模式一致

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

權(quán)限permission

權(quán)限 ACL簡寫 描述
CREATE c 可以創(chuàng)建子節(jié)點
DELETE d 可以刪除子節(jié)點(僅下一級節(jié)點)
READ r 可以讀取節(jié)點數(shù)據(jù)及顯示子節(jié)點列表
WRITE w 可以設(shè)置節(jié)點數(shù)據(jù)
ADMIN a 可以設(shè)置節(jié)點訪問控制列表權(quán)限

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

權(quán)限相關(guān)命令

命令 使用方式 描述
getAcl getAcl 讀取ACL權(quán)限
setAcl setAcl 設(shè)置ACL權(quán)限
addauth addauth 添加認證用戶

?示例:World方案

[zk: localhost:2181(CONNECTED) 0] create /node1 1
Created /node1
 
[zk: localhost:2181(CONNECTED) 1] getAcl /node1
'world,'anyone  #默認為world方案
: cdrwa #任何人都擁有所有權(quán)限

示例:IP方案

#創(chuàng)建節(jié)點
[zk: localhost:2181(CONNECTED) 0] create /node2 1
Created /node2

#設(shè)置權(quán)限(只有ip地址為192.168.66.100的客戶端才能操作該節(jié)點)
[zk: localhost:2181(CONNECTED) 1] setAcl /node2 ip:192.168.66.100:cdrwa 


#使用IP非 192.168.66.100 的機器
[zk: localhost:2181(CONNECTED) 0] get /node2
Authentication is not valid : /node2 #沒有權(quán)限

示例:Auth方案

#創(chuàng)建節(jié)點
[zk: localhost:2181(CONNECTED) 0] create /node3 1
Created /node3

#添加認證用戶zj,密碼123456
[zk: localhost:2181(CONNECTED) 1] addauth digest zj:123456

#為創(chuàng)建的權(quán)限用戶zj設(shè)置權(quán)限
[zk: localhost:2181(CONNECTED) 2] setAcl /node3 auth:zj:cdrwa

#獲取權(quán)限
[zk: localhost:2181(CONNECTED) 3] getAcl /node3
'digest,'zj:UvJWhBril5yzpEiA2eV7bwwhfLs=
: cdrwa


示例:Digest方案

#密碼加密
echo -n zj:123456 | openssl dgst -binary -sha1 | openssl base64
UvJWhBril5yzpEiA2eV7bwwhfLs=


#創(chuàng)建節(jié)點
[zk: localhost:2181(CONNECTED) 0] create /node4 1
Created /node4

#使用是算好的密文密碼添加權(quán)限:
[zk: localhost:2181(CONNECTED) 1] setAcl /node4 digest:zj:UvJWhBril5yzpEiA2eV7bwwhfLs=:cdrwa

 #獲取節(jié)點數(shù)據(jù)沒有權(quán)限
[zk: localhost:2181(CONNECTED) 3] get /node4
Authentication is not valid : /node4

#添加認證用戶
[zk: localhost:2181(CONNECTED) 4] addauth digest zj:123456

#成功讀取數(shù)據(jù)
[zk: localhost:2181(CONNECTED) 5] get /node4 1 

四、原生api操作Zookeeper

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?利用Zookeeper官方的原生java api進行連接,然后演示一些創(chuàng)建、刪除、修改、查詢節(jié)點的操作。

1.創(chuàng)建maven項目,引入依賴。

<dependencies>
  <dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.8</version>
  </dependency>
</dependencies>

2.創(chuàng)建連接和節(jié)點

注意:在使用Java連接zookeeper服務(wù)的時候先要在虛擬機開啟zookeeper的服務(wù)。(zkSserver.sh start)

public class ZKMain {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //1.創(chuàng)建與服務(wù)端的對話
        /**
         * 第一個參數(shù):zookeeper的服務(wù)地址
         * 第二個參數(shù):會話超時時間
         * 第三個參數(shù):監(jiān)聽機制
         */
        ZooKeeper zooKeeper = new ZooKeeper("192.168.66.100:2181," +
                                                         "192.168.66.101:2181," +
                                                          "192.168.66.102:2181", 4000, null);
        //2.查看連接狀態(tài)
        System.out.println(zooKeeper.getState());

        //3.創(chuàng)建節(jié)點
        /*
         * 第一個參數(shù):節(jié)點的名字
         * 第二個參數(shù):節(jié)點的數(shù)據(jù)
         * 第三個參數(shù):節(jié)點的權(quán)限策略
         *            ZooDefs.Ids.OPEN_ACL_UNSAFE:完全開放任何人都能操作
         *            ZooDefs.Ids.CREATOR_ALL_ACL:創(chuàng)建者才能操作
         *            ZooDefs.Ids.READ_ACL_UNSAFE:只讀權(quán)限
         * 第四個參數(shù):節(jié)點類型(持久、臨時、……)
         *           CreateMode.PERSISTENT:持久型節(jié)點
         *           CreateMode.EPHEMERAL:臨時節(jié)點
         *           CreateMode.PERSISTENT_SEQUENTIAL:持久順序節(jié)點
         *           CreateMode.EPHEMERAL_SEQUENTIAL:臨時順序節(jié)點
         */
            zooKeeper.create("/zkTest","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    }
}

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

znode 類型有四種?

  • PERSISTENT - 持久化目錄節(jié)點,客戶端與zookeeper斷開連接后,該節(jié)點依舊存在
  • PERSISTENT_SEQUENTIAL - 持久化,并帶有序列號
  • EPHEMERAL - 臨時目錄節(jié)點,客戶端與zookeeper斷開連接后,該節(jié)點被刪除
  • EPHEMERAL_SEQUENTIAL - 臨時,并帶有序列號

?3.修改節(jié)點數(shù)據(jù)

       //5.修改節(jié)點
        /**
         * 參數(shù)一:節(jié)點名稱
         * 參數(shù)二:修改的數(shù)據(jù)
         * 參數(shù)三:版本,全部修改設(shè)為-1
         */
        zooKeeper.setData("/zkTest","2".getBytes(),-1);

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

4.獲取節(jié)點數(shù)據(jù)和節(jié)點信息

        //6.獲取節(jié)點數(shù)據(jù)
        /**
         * 參數(shù)一:節(jié)點名稱
         * 參數(shù)二:監(jiān)聽機制
         * 參數(shù)三:狀態(tài)信息
         */
        byte[] data = zooKeeper.getData("/zkTest", null, null);
        System.out.println(new String(data));

        //7.獲取節(jié)點的子節(jié)點信息
        /**
         * 參數(shù)一:節(jié)點名稱
         * 參數(shù)二:監(jiān)聽機制
         */
        List<String> children = zooKeeper.getChildren("/zkTest", null);
        for (String child : children) {
            System.out.println(child);
        }

5.監(jiān)聽節(jié)點

public class ZKWatcher {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //1.創(chuàng)建與服務(wù)端的對話
        /*
         * 第一個參數(shù):zookeeper的服務(wù)地址
         * 第二個參數(shù):會話超時時間
         * 第三個參數(shù):監(jiān)聽機制,接口類型,使用匿名內(nèi)部類實現(xiàn)該接口
         */
        ZooKeeper zooKeeper = new ZooKeeper("192.168.66.100:2181," +
                "192.168.66.101:2181," +
                "192.168.66.102:2181", 4000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("正在監(jiān)聽……");
            }
        });

        //2.注冊監(jiān)聽機制監(jiān)聽節(jié)點
        zooKeeper.getChildren("/zkTest", new Watcher() {

            /*對 /zkTest 的子節(jié)點進行操作的時候會回調(diào)該監(jiān)聽方法*/
            @Override
            public void process(WatchedEvent watchedEvent) {
                //查看監(jiān)聽路徑
                System.out.println("監(jiān)聽路徑:"+watchedEvent.getPath());
                //查看監(jiān)聽的事件
                System.out.println("監(jiān)聽的事件:"+watchedEvent.getType());
            }
        });

        //線程休眠,保持持續(xù)監(jiān)聽
        Thread.sleep(Long.MAX_VALUE);
    }
}

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

刪除 /zkTest 的子節(jié)點? /zkTest1 節(jié)點的數(shù)據(jù)時觸發(fā)監(jiān)聽:

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

?6.監(jiān)聽節(jié)點數(shù)據(jù)

package com.zj;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;

public class ZKWatcher {
    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //1.創(chuàng)建與服務(wù)端的對話
        /*
         * 第一個參數(shù):zookeeper的服務(wù)地址
         * 第二個參數(shù):會話超時時間
         * 第三個參數(shù):監(jiān)聽機制,接口類型,使用匿名內(nèi)部類實現(xiàn)該接口
         */
        ZooKeeper zooKeeper = new ZooKeeper("192.168.66.100:2181," +
                "192.168.66.101:2181," +
                "192.168.66.102:2181", 4000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("正在監(jiān)聽……");
            }
        });



        //3.監(jiān)聽節(jié)點數(shù)據(jù)
        zooKeeper.getData("/zkTest", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //查看監(jiān)聽路徑
                System.out.println("監(jiān)聽路徑:"+watchedEvent.getPath());
                //查看監(jiān)聽的事件
                System.out.println("監(jiān)聽的事件:"+watchedEvent.getType());
            }
        },null);

        //線程休眠,保持持續(xù)監(jiān)聽
        Thread.sleep(Long.MAX_VALUE);
    }
}

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

修改 /zkTest 節(jié)點的數(shù)據(jù):

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

注意:?

?通過zooKeeper.getchildren("/",new watch()){}來注冊監(jiān)聽,監(jiān)聽的是整個根節(jié)點,但是這個監(jiān)聽只能監(jiān)聽一次。線程休眠是為了讓監(jiān)聽等待事件發(fā)生,不然會隨著程序直接運行完。

五、zkClient操作Zookeeper

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

使用zookeeper遇到問題:

  • 重復注冊watcher
  • session失效重連
  • 異常處理(刪除節(jié)點不能有子節(jié)點,新增節(jié)點必須有父節(jié)點等)

?zkclient是Github上一個開源的Zookeeper客戶端,在Zookeeper原生 API接口之上進行了包裝,是一個更加易用的Zookeeper客戶端。同時Zkclient在內(nèi)部實現(xiàn)了諸如Session超時重連,Watcher反復注冊等功能,從而提高開發(fā)效率。

添加依賴

<dependency>
   <groupId>com.101tec</groupId>
   <artifactId>zkclient</artifactId>
   <version>0.10</version>
</dependency>

創(chuàng)建會話

  //1.創(chuàng)建會話
  ZkClient zkClient = new ZkClient("192.168.66.100:2181,192.168.66.101:2181,192.168.66.102:2181");

創(chuàng)建節(jié)點

 //3.創(chuàng)建節(jié)點
 zkClient.create("/zkTest/zkTest3","3", CreateMode.PERSISTENT);

獲取/zkTest子節(jié)點

//2.獲取/zkTest子節(jié)點
List<String> children = zkClient.getChildren("/zkTest");
children.forEach(System.out::println);

修改節(jié)點數(shù)據(jù)

zkClient.writeData("/zkTest/zkTest3","4");

獲取節(jié)點數(shù)據(jù)

 //5.獲取節(jié)點數(shù)據(jù)
 String data = zkClient.readData("/zkTest/zkTest3");

刪除節(jié)點

//6.刪除節(jié)點
zkClient.delete("/zkTest/zkTest3");

注冊節(jié)點監(jiān)聽事件

        //7.注冊節(jié)點監(jiān)聽事件
        zkClient.subscribeChildChanges("/zkTest",new IZkChildListener(){

            @Override
            public void handleChildChange(String s, List<String> list) throws Exception {
                System.out.println("節(jié)點改變了");
                list.forEach(System.out::println);
            }
        });

注冊數(shù)據(jù)監(jiān)聽事件

        //8.注冊數(shù)據(jù)監(jiān)聽事件
        zkClient.subscribeDataChanges("/zkTest", new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
                System.out.println("數(shù)據(jù)改變了");
            }

            @Override
            public void handleDataDeleted(String s) throws Exception {
                System.out.println("數(shù)據(jù)刪除了");
            }
        });

六、ApacheCurator操作Zookeeper

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

Curator是 Netflix公司開源的一套ZooKeeper客戶端框架。和ZkClient一樣,Curator解決了很多ZooKeeper客戶端非常底層的細節(jié)開發(fā)工作,包括連接重連、反復注冊Watcher和 NodeExistsException異常等,目前已經(jīng)成為了Apache的頂級項目,是全世界范圍內(nèi)使用最廣泛的ZooKeeper客戶端之一。

Curator包

  • curator-framework:對zookeeper的底層api的一些封裝。
  • curator-client:提供一些客戶端的操作,例如重試策略等。
  • curator-recipes:封裝了一些高級特性,如:Cache事件監(jiān)聽、選舉、分布式鎖、分布式計數(shù)器、分布式Barrier等。

添加Maven依賴

<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-recipes</artifactId>
   <version>4.2.0</version>
</dependency>

創(chuàng)建會話

        //1.創(chuàng)建會話
        String connStr = "192.168.66.100:2181,192.168.66.101:2181,192.168.66.102:2181";
        CuratorFramework cur= CuratorFrameworkFactory.builder()
                .connectString(connStr)
                .connectionTimeoutMs(5000)
                .retryPolicy(new ExponentialBackoffRetry(1000,3)) //斷開重試機制
                .build();
        //2.連接
        cur.start();連接

創(chuàng)建節(jié)點

 //3.創(chuàng)建節(jié)點
     cur.create().withMode(CreateMode.PERSISTENT).forPath("/zkTest/zkTest4","4".getBytes());

獲取數(shù)據(jù)

        //4.獲取數(shù)據(jù)
        byte[] bytes = cur.getData().forPath("/zkTest/zkTest4");
        System.out.println(new String(bytes));

刪除一個節(jié)點

        //5.刪除節(jié)點
        cur.delete().forPath("/zkTest/zkTest4");

注意:

此方法只能刪除葉子節(jié)點,否則會拋出異常。

刪除一個節(jié)點,并且遞歸刪除其所有的子節(jié)點

cur.delete().deletingChildrenIfNeeded().forPath("/zkTest");

更新一個節(jié)點的數(shù)據(jù)內(nèi)容

client.setData().forPath("path","data".getBytes());

監(jiān)聽節(jié)點

        //8.監(jiān)聽機制
        NodeCache nodeCache = new NodeCache(cur, "/zkTest/zkTest3");
        nodeCache.getListenable().addListener(()-> System.out.println("被修改"));
        nodeCache.start();

七、Zookeeper高級

7.1?四字命令

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

之前使用stat命令來驗證ZooKeeper服務(wù)器是否啟動成功,這里的stat命令就是ZooKeeper 中最為典型的命令之一。ZooKeeper中有很多類似的命令,它們的長度通常都是4個英文字母,因此我們稱之為“四字命令”。

添加配置(前提)

vim zoo.cfg

#開啟四字命令
4lw.commands.whitelist=*


#添加nc命令
yum install nc -y

conf

輸出Zookeeper相關(guān)服務(wù)的詳細配置信息,如客戶端端口,數(shù)據(jù)存儲路徑、最大連接數(shù)、日志路徑、數(shù)據(jù)同步端口、主節(jié)點推舉端口、session超時時間等等。

echo conf| nc localhost 2181

注意:

注意,conf命令輸出的配置信息僅僅是輸出一些最基本的配置參數(shù)。另外,conf命令會根據(jù)當前的運行模式來決定輸出的信息。如果是單機模式(standalone), 就不會輸出諸如initLimit.syncLimit、electionAlg 和electionPort等集群相關(guān)的配置信息。

cons

cons 命令用于輸出當前這臺服務(wù)器上所有客戶端連接的詳細信息,包括每個客戶端的客戶端IP、會話ID和最后一次與服務(wù)器交互的操作類型等。

echo cons | nc localhost 2181

ruok

ruok命令用于輸出當前ZooKeeper服務(wù)器是否正在運行。該命令的名字非常有趣,其諧音正好是“Are you ok”。執(zhí)行該命令后,如果當前ZooKeeper服務(wù)器正在運行,那么返回“imok”, 否則沒有任何響應(yīng)輸出。

echo ruok | nc localhost 2181

stat

stat命令用于獲取ZooKeeper服務(wù)器的運行時狀態(tài)信息,包括基本的ZooKeeper版本、打包信息、運行時角色、集群數(shù)據(jù)節(jié)點個數(shù)等信息,另外還會將當前服務(wù)器的客戶端連接信息打印出來。

echo stat | nc localhost 2181

注意:

除了一些基本的狀態(tài)信息外,stat命令還會輸出一些服務(wù)器的統(tǒng)計信息,包括延遲情況、收到請求數(shù)和返回的響應(yīng)數(shù)等。注意,所有這些統(tǒng)計數(shù)據(jù)都可以通過srst命令進行重置。

mntr

列出集群的關(guān)鍵性能數(shù)據(jù),包括zk的版本、最大/平均/最小延遲數(shù)、數(shù)據(jù)包接收/發(fā)送量、連接數(shù)、zk角色(Leader/Follower)、node數(shù)量、watch數(shù)量、臨時節(jié)點數(shù)。

echo mntr | nc localhost 2181

7.2?選舉機制

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

核心選舉原則

  • Zookeeper集群中只有超過半數(shù)以上的服務(wù)器啟動,集群才能正常工作;
  • 在集群正常工作之前,myid小的服務(wù)器給myid大的服務(wù)器投票,直到集群正常工作,選出Leader;
  • 半數(shù)機制;

分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù),java后端,分布式,zookeeper,云原生

選舉機制流程

  • 服務(wù)器1啟動,給自己投票,然后發(fā)投票信息,由于其它機器還沒有啟動所以它收不到反饋信息,服務(wù)器1的狀態(tài)一直屬于Looking(選舉狀態(tài))。
  • 服務(wù)器2啟動,給自己投票,同時與之前啟動的服務(wù)器1交換結(jié)果,由于服務(wù)器2的編號大所以服務(wù)器2勝出,但此時投票數(shù)沒有大于半數(shù),所以兩個服務(wù)器的狀態(tài)依然是LOOKING。
  • 服務(wù)器3啟動,給自己投票,同時與之前啟動的服務(wù)器1,2交換信息,由于服務(wù)器3的編號最大所以服務(wù)器3勝出,此時投票數(shù)正好大于半數(shù),所以服務(wù)器3成為領(lǐng)導者,服務(wù)器1,2成為小弟。
  • 服務(wù)器4啟動,給自己投票,同時與之前啟動的服務(wù)器1,2,3交換信息,盡管服務(wù)器4的編號大,但之前服務(wù)器3已經(jīng)勝出,所以服務(wù)器4只能成為小弟。
  • 服務(wù)器5啟動,后面的邏輯同服務(wù)器4成為小弟。

選擇機制中的概念

Serverid:服務(wù)器ID

比如有三臺服務(wù)器,編號分別是1,2,3。

?編號越大在選擇算法中的權(quán)重越大。

Zxid:數(shù)據(jù)ID

服務(wù)器中存放的最大數(shù)據(jù)ID.

?值越大說明數(shù)據(jù)越新,在選舉算法中數(shù)據(jù)越新權(quán)重越大。

Epoch:邏輯時鐘

或者叫投票的次數(shù),同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個數(shù)據(jù)就會增加,然后與接收到的其它服務(wù)器返回的投票信息中的數(shù)值相比,根據(jù)不同的值做出不同的判斷。文章來源地址http://www.zghlxwxcb.cn/news/detail-521968.html

到了這里,關(guān)于分布式調(diào)用與高并發(fā)處理 Zookeeper分布式協(xié)調(diào)服務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【分布式】Zookeeper

    可以參考:https://zhuanlan.zhihu.com/p/62526102 ZooKeeper 是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)同服務(wù)。ZooKeeper 的設(shè)計目標是將那些復雜且容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并以一系列簡單易用的接口提供給用戶使用。 配置管理。 Java微服

    2024年02月11日
    瀏覽(43)
  • 分布式服務(wù)框架_Zookeeper--管理分布式環(huán)境中的數(shù)據(jù)

    安裝和配置詳解 本文介紹的 Zookeeper 是以 3.2.2 這個穩(wěn)定版本為基礎(chǔ),最新的版本可以通過官網(wǎng) ? http://hadoop.apache.org/zookeeper/ 來獲取, Zookeeper 的安裝非常簡單,下面將從單機模式和集群模式兩個方面介紹 Zookeeper 的安裝和配置。 單機模式

    2024年02月12日
    瀏覽(23)
  • 分布式鎖原理與實戰(zhàn)三:ZooKeeper分布式鎖的原理

    分布式鎖原理與實戰(zhàn)三:ZooKeeper分布式鎖的原理

    ???????? 目錄 ZooKeeper分布式鎖的原理 ZooKeeper的每一個節(jié)點,都是一個天然的順序發(fā)號器。 ZooKeeper節(jié)點的遞增有序性,可以確保鎖的公平 ZooKeeper的節(jié)點監(jiān)聽機制,可以保障占有鎖的傳遞有序而且高效 ZooKeeper的節(jié)點監(jiān)聽機制,能避免羊群效應(yīng) 分布式鎖的搶占過程 客戶端

    2024年02月08日
    瀏覽(17)
  • ZooKeeper的分布式鎖

    ZooKeeper的分布式鎖機制主要利用ZooKeeper的節(jié)點特性,通過創(chuàng)建和刪除節(jié)點來實現(xiàn)鎖的控制。 實現(xiàn)步驟: 創(chuàng)建鎖節(jié)點:當一個進程需要訪問共享資源時,它會在ZooKeeper中創(chuàng)建一個唯一的臨時順序節(jié)點作為鎖。 嘗試獲取鎖:進程會查看當前所有的鎖節(jié)點,檢查自己創(chuàng)建的節(jié)點是

    2024年04月22日
    瀏覽(19)
  • 分布式協(xié)調(diào)組件Zookeeper

    分布式協(xié)調(diào)組件Zookeeper

    ZooKeeper 是?種 分布式協(xié)調(diào)組件 ,用于管理大型主機。 在分布式環(huán)境中協(xié)調(diào)和管理服務(wù)是一個復雜的過程 。ZooKeeper 通過其簡單的架構(gòu)和 API 解決了這個問題。ZooKeeper 允許開發(fā)人員專注于核心應(yīng)用程序邏輯,而不必擔心應(yīng)用程序的分布式特性。 分布式協(xié)調(diào)組件 在分布式系統(tǒng)

    2024年02月13日
    瀏覽(22)
  • Zookeeper實現(xiàn)分布式鎖

    Zookeeper實現(xiàn)分布式鎖

    ZooKeeper是一個分布式協(xié)調(diào)服務(wù),其中提供的序列化、持久化、有層次的目錄結(jié)構(gòu)使得它非常適合用于實現(xiàn)分布式鎖。在ZooKeeper中,分布式鎖通常通過臨時有序節(jié)點實現(xiàn)。以下是ZooKeeper分布式鎖的詳細介紹: ?實現(xiàn)方式: 臨時有序節(jié)點: 當一個客戶端需要獲取鎖時,它在ZooK

    2024年02月02日
    瀏覽(30)
  • Zookeeper 分布式鎖案例

    Zookeeper 是一個開源的分布式協(xié)調(diào)服務(wù),可以用于維護分布式系統(tǒng)中的一致性、順序性和命名等。其中,Zookeeper 的分布式鎖機制可以用于實現(xiàn)分布式系統(tǒng)中的互斥訪問,確保在多個節(jié)點上對共享資源進行同步訪問。 Zookeeper 分布式鎖的實現(xiàn)原理是基于 Zookeeper 的臨時有序節(jié)點和

    2024年02月16日
    瀏覽(32)
  • zookeeper偽分布式安裝

    zookeeper偽分布式安裝

    需要有jdk1.8 (1)將zookeeper的安裝包上傳到/opt/modules目錄下 (2)解壓 (3)更名 切換到/opt/installs目錄下 (4)配置環(huán)境變量 切換到/opt/installs/zookeeper3.6.3/conf目錄下

    2024年02月17日
    瀏覽(27)
  • 分布式鎖實現(xiàn)方案-基于zookeeper的分布式鎖實現(xiàn)(原理與代碼)

    分布式鎖實現(xiàn)方案-基于zookeeper的分布式鎖實現(xiàn)(原理與代碼)

    目錄 一、基于zookeeper的分布式鎖 1.1 基于Zookeeper實現(xiàn)分布式鎖的原理 1.1.1 分布式鎖特性說明 1.1.1.1 特點分析 1.1.1.2 本質(zhì) 1.1.2 Zookeeper 分布式鎖實現(xiàn)原理 1.1.2.1 Zookeeper臨時順序節(jié)點特性 1.1.2.2 Zookeeper滿足分布式鎖基本要求 1.1.2.3 Watcher機制 1.1.2.3 總結(jié) 1.2 分布式鎖流程說明 1.2.1

    2024年04月24日
    瀏覽(28)
  • 【分布式鎖】06-Zookeeper實現(xiàn)分布式鎖:可重入鎖源碼分析

    前言 前面已經(jīng)講解了Redis的客戶端Redission是怎么實現(xiàn)分布式鎖的,大多都深入到源碼級別。 在分布式系統(tǒng)中,常見的分布式鎖實現(xiàn)方案還有Zookeeper,接下來會深入研究Zookeeper是如何來實現(xiàn)分布式鎖的。 Zookeeper初識 文件系統(tǒng) Zookeeper維護一個類似文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu) image.png 每

    2024年02月22日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包