Zookeeper與Dubbo微服務實戰之Zookeeper篇

文章目錄

zookeeper環境搭建

linux下jdk環境搭建

一、安裝jdk

jdk1.8.0_211鏈接
zookeeper鏈接,新版本只有帶bin的是編譯過的更是我們需要的,另一個版本只是源碼
1、將jdk和zookeeper通過ftp轉移到linux /home下
2、解壓jdk和zookeeper到/usr/和/usr/local下
解壓jdk和zookeeper
tar -zxvf ....jdk
tar -zxvf ...zookeeper
修改解壓之後的jdk和zookeeper的名字
mv XXX jdk8
mv YYY zookeeper
轉移jdk和zookeeper
mv jdk8 /usr
mv zookeeper /usr/local
2、配置jdk和zookeeper環境變量
修改配置文件 vim /etc/profile
export JAVA_HOME=/usr/jdk8
export ZOOKEEPER_HOME=/usr/local/zookeeper
export CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin
配置完環境變量測試一下是否成功
測試之前先刷新配置文件
source /etc/profile
//測試
java -version

二、zookeeper配置文件

複製zookeeper/conf/zookeeper.cfg文件

cp zookeeper.cfg zoo.cfg

1、tickTime

Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔。 也就是每隔 tickTime 時間就會發送一個心跳。以毫秒爲單位,比如session超時 N*tickTime

2、initLimit

用於集羣,允許從節點鏈接並同步到master節點的初始化連接時間,以tickTime的倍數來表示。

3、syncLimit

用於集羣,master主節點與從節點之間發送消息,請求和應答時間長度(心跳機制),超時從節點就會被拋棄

4、dataDir

必須配置
但是不能配置到臨時文件夾裏面
dataDir=/tmp/zookeeper
修改爲
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir

5、dataLogDir

日誌目錄,如果不配置會和dataDir公用

6、clientport

連接服務器的端口,默認2181

三、啓動zookeeper

//啓動
./zkServer.sh start
//重啓,現關閉再開啓
./zkServer.sh restart
//查看狀態
./zkServer.sh status

3-1 zk數據模型介紹

1、樹形結構
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ygF1mlkK-1575608668526)(en-resource://database/1749:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-djztQuLN-1575608668527)(en-resource://database/1751:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Vc99c9ml-1575608668528)(en-resource://database/1753:1)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YGV94rXQ-1575608668528)(en-resource://database/1755:1)]

3-2 zookeeper數據模型的基本操作

  1. 客戶端連接
    ./zkCli.sh打開命令行後臺
    連接到Connecting to localhost:2181
    Ctrl+C退出當前客戶端
  2. 查看znode結構
  3. 關閉客戶端連接

3-3 zookeeper的作用

1、高可用,當master掛了之後,後續的從節點就會替補上去,不讓讓系統崩掉,這也叫做首腦模式,保證集羣的高可用,高可用的體現之一,局長死了,副局長立馬頂上
2、統一配置文件管理,只需要部署一臺服務器,則可以吧相同的配置文件同步更新到其他服務器,此操作在雲計算中非常多(假設修改了redis統一配置)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZGMp7qyF-1575608668529)(en-resource://database/1757:1)]
3、發佈與訂閱,例如消息隊列MQ,發佈者將信息發佈到節點,二訂閱了節點的訂閱者就會收到這個信息,相應的進行改變
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Ic7PjXA0-1575608668530)(en-resource://database/1759:1)]
4、提供分佈式鎖,分佈式環境中,不同進程的資源爭搶,類似以多線程中的鎖(爲什麼zookeeper能提供分佈式鎖呢,歸因於zookeeper的結構,在zookeeper的結構中,增加節點是往後續的,即一個個增加在後面,類似於隊列,所以第一個就是相當於master,這個唯一就是鎖)
5、集羣管理,集羣保證數據的強一致性
比如客戶端連接了主節點,並且增加數據Data-XYZ,那麼由於集羣的機制會進行同步,那麼從節點酒也有了這個數據,客戶端斷開之後,連接其他節點也會讀到相同的信息(類似於2統一文件-配置)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xgLMpyzY-1575608668530)(en-resource://database/1761:1)]

4-1 zookeeper的常用命令

  1. ./zkCli.sh 打開命令行後臺
  2. ls和ls2
    ls查看目錄 ls /zookeeper
    ls2是查看節點狀態信息 ls2 /
    ls2相當於ls和stat
  3. stat 查看狀態信息
  4. get 當前節點的數據取出來
    czxid 節點創建的id
    ctime 節點創建的時間
    mzxid 節點修改的id
    mtime 節點修改的時間
    pzxid 子節點的id
    cversion 子節點的版本
    dataVersion 數據的版本
    aclVersion 節點權限修改的版本
    ephemeralOwner 之後再說
    dataLength 數據長度
    numChildren 下面子節點的個數

4-2 session的基本原理

基本原理一
  1. 客戶端與服務器之間的連接存在會話
  2. 每個會話都會可以設置一個超時時間
  3. 心跳結束,則Session過期
    因爲每個心跳都會向服務器發送一個(ping包?)信息,從而保證服務器知道session還活着
基本原理二
  1. Session過期,則臨時節點znode會被拋棄
  2. 心跳機制:客戶端向服務器的ping包請求
創建節點
創建默認節點(持久存在)

create /imooc immoc-data

創建臨時節點(斷開連接後,心跳結束不存在)

cerate -e /imooc/tmp tmp-data

如何識別是臨時節點?
不是臨時節點:ephemeralOwner=0x0
是臨時節點::ephemeralOwner=0x0…
當zookeeper連接關閉時,臨時節點不會立馬被刪除,臨時節點默認存在一個心跳時間,等這個時間過後纔會被刪除

創建順序節點(持久存在)

create -s /immoc/seq seq-data
ls /imooc
[seq0000000001]

創建的順序節點從1開始

create -s /imooc/seq seq-data
ls /imooc
[seq0000000001, seq0000000002]
創建時節點序號是依次遞增的

修改節點

set [-s] [-v version] path data

set /imooc new-data 修改之後,mtime、dataVersion、dataLength就會發生變化
dataVersion遞增1

在指定版本號的節點,進行修改的情況

①、set -v 1 /imooc new
②、set -v 1 /imooc new

發生錯誤version No is not valid : /imooc
原因是①更新節點之後,dataVersion自增1變爲了2,②更新的時候版本號已經不是1了,所以纔會導致版本號不可校驗,這可以做到樂觀鎖的效果,所以在併發的時候,由於版本號的問題,就不會導致併發錯誤

所以只能修改最新版本號的節點(不加版本號,默認修改最新版本的節點),修改其他版本的節點,就會出錯

刪除節點

delete [-v version] path

其他問題同上述修改節點

4-3 zk特性 watcher機制

一:

  1. 針對每個節點的操作,都會有一個監督者→watcher
  2. 當監控的某個對象(znode)發生變化,則觸發watcher事件
  3. zk中的watcher是一次性的,觸發後立即銷燬

二:

  1. 父節點、子節點都能觸發watcher
  2. 針對不同的操作,watcher能表現不同的反應
    (子)節點刪除事件
    (子)節點修改事件
    (子)節點變化事件
    當(子)節點發生變化時,觸發watcher相應的事件,客戶端在收到這個事件之後,比對事件名,然後做出自己的操作,比如節點發出刪除事件,watcher發送給客戶端,客戶端接收到這個事件之後,匹配成功,然後再刪了與這個節點的連接

4-4 父節點watcher事件

  1. 創建父節點觸發:NodeCreate

使用 stat [-w] path 爲節點添加watcher
增加imooc節點的watcher
stat -w /imooc
創建/imooc節點
create /imooc watcher-test
WATCHER::WatchedEvent state:SyncConnected type:NodeCreated path:/imooc

  1. 修改父節點數據觸發:NodeDataChanged

使用 get -w path爲節點添加watcher
get -w /imooc
set /imooc new-data
WATCHER::WatchedEvent state:SyncConnected type:NodeDataChanged path:/imooc

  1. 刪除父節點觸發:NodeDeleted

使用 get -w path爲節點添加watcher
get -w /imooc
delete /imooc
WATCHER::WatchedEvent state:SyncConnected type:NodeDeleted path:/imooc

4-5 子節點watcher事件

  1. ls爲父節點(必須先存在父節點)設置watcher,創建子節點觸發:NodeChildrenChanged
  2. ls爲父節點設置watcher,刪除子節點觸發:NodeChildrenChanged
  3. ls爲父節點設置watcher,修改子節點不觸發事件
    如果需要讓子節點觸發事件,那麼就需要在這各自節點上設置watcher事件,觸發NodeChanged事件

4-6 watcher使用場景

統一資源配置

4-7 權限ACL

ACL(Access control lists)權限控制
  1. 針對節點可以設置相關讀寫等權限,目的是爲了保證數據安全性
  2. 權限permissions可以指定不同的權限範圍以及角色
ACL命令行
  1. getAcl 得到某個節點路徑的acl權限信息
    getAcl path
  2. setAcl 設置某個節點路徑的acl權限
    setAcl path acl
  3. addauth 輸入認證授權信息,註冊時輸入明文密碼(登錄)但是在zk的系統中,密碼是以加密的形式存在的
    addauth scheme auth
ASL的構成一
  1. zk的acl是通過[scheme🆔permission]來構成權限列表

scheme:權限模式,代表採用的某種權限機制,五種(常用四種)
id:代表允許訪問的用戶
permission:權限組合字符串

ACL的構成二 - Scheme
  1. world:world下只有一個id,那就是anyone,組合寫法就是world:anyone:[permissions]
  2. auth:代表認證登錄,需要註冊用戶有權限就可以,形式爲:auth:user:password:[permissions]
  3. digest:需要對密碼加密才能訪問,組合格式爲digest:username:BASE64(SHA1(password)):[permissions]
    auth與digest的區別就是:一個明文、一個密文、需要不同的訪問方式

setAcl /path auth:lee:lee:cdrwa
setAcl /path digest:lee:BASE64(SHA1(lee)):cdrwa

一般auth用的不多,因爲生產環境總是要加密的
addauth digest lee:lee 後都能操作指定節點的權限
4. ip:當設置爲ip指定的ip地址,此時限制ip進行訪問,比如ip:192.168.1.1:[permissions]
因爲用的是集羣,那麼比如一個訂單服務的ip是192.168.1.1,還有一個是192.168.1.2那麼只有這兩個ip可以訪問這個節點,其他的比如報賬服務就不能訪問這個節點
5. super:代表超級管理員,擁有所有的權限,這個很危險,一般給運維或者研發經理或者CTO,所以一般不用,常用前四個

4-8 acl的構成 permission的構成

權限字符串縮寫:crdwa
  1. CREATE:創建子節點,不能創建節點
  2. READ:獲取節點/子節點
  3. WRITE:設置節點數據
  4. DELETE:刪除子節點
  5. ADMIN:設置權限

4-9 acl的命令行 world講解

world:anyone:crawd

設置節點的權限

4-10 acl命令行 auth講解

auth:user:pwd:crawd
digest:userBASE64(SHA1(pwd)):crawd
addauth digest user:pwd

再給節點設置權限時,先登錄,然後再給登錄對象設置權限

addauth digest user:pwd
setAcl path auth:user:pwd:[permissions]
getAcl path

4-11 acl命令行 digest講解

登錄和auth一樣

addauth digest imooc:imocc
setAcl path digest:imooc:(imooc的密文):[permissions]

4-11 acl命令行 ip講解

setAcl path ip:(ip地址):[permissions]

在之後的java客戶端連接中,我們再來演示

4-12 acl之super超級管理員

場景:創建一個ipd能訪問的節點,在這我們使用超級管理員賬號去訪問該節點

創建一個ip能訪問的節點

create /names/ip xxx.xxx.xxx.xxx
setAcl /names/ip ip:xxx.xxx.xxx.xxx:crawd

修改配置文件,添加超級管理員賬號

vim zkServer.sh

在nohup塊中添加超級管理員賬號密碼(密文imooc,經過sha1和base64加密得到XwEDaL3J0JQGkRQzM0DpO6zMzZs=)

“-Dzookeeper.DigestAuthenticationProvider.superDigest=imooc:XwEDaL3J0JQGkRQzM0DpO6zMzZs=”\

重啓zookeeper

./zkServer.sh restart

登錄超級管理員
addauth digest imooc:imooc
getAcl /names/ip

如果沒有登陸,或者登錄的其他賬號,則都不能訪問該節點

4-13 acl的常用場景

  1. 開發/測試環境分離,開發者無權操作測試庫的節點,只能看
  2. 生產環境控制指定ip的服務可以訪問相關節點,防止混亂,由於有些是動態ip,有可能有點不方便

4-14 zk四字命令 Four letter words

  1. zk可以通過它自身提供的簡寫命令來和服務器進行交互
  2. 需要使用到nc命令 ,安裝yum install nc
  3. echo [commond] | nc [ip] [port]
    【stat】:查看zk的狀態信息,以及是否mode
    【ruok】:查看當前zkServer是否啓動,返回imok
    【dump】:列出未經處理的會話和臨時節點
    【conf】:查看相關配置信息
    【cons】:展示連接到客戶端的連接信息i
    【envi】:環境變量,jdk,zookeeper等
    【mntr】:監控zk的健康信息
    【wchs】:展示watch的信息
    【wchc與wchp】:session與watch及path與watch信息
    注:如果報錯例如:
    ruok is not executed because it is not in the whitelist.解決方法請看https://blog.csdn.net/x763795151/article/details/80599498

注:查看zookeeper事務日誌
在配置文件zoo_sample.cfg中,事務日誌和快照日誌,默認在dataDir中
在配置了zoo.cfg之後,事務日誌和快照日誌分離,事務日誌在在我們配置的dataLogDir中

由於事務日誌是二進制數據,因此用vi/vim不能查看得到,因此只能解碼後查看

mkdir /use/log
cd /usr/local/zookeeper/lib
cp slf4j-api.1.7.25.jar zookeeper.3.5.6.jar zookeeper.jute.3.5.6.jar /usr/log

java -classpath .:slf4j-api.1.7.25.jar:zookeeper.3.5.6.jar:zookeeper.jute.3.5.6.jar org.apache.zookeeper.LogFormatter /usr/local/zookeeper/dataLogDir/version-2/log.4e

1.創建一個文件夾log保存我們所需要的jar包
2.切換到zookeeper的lib文件夾下
3.複製所需要jar包到log中
4.編寫解碼信息
/usr/local/zookeeper/dataLogDir/version-2/log.4e
是我們的事務日誌路徑

注:測試ookeeper版本爲3.5.6
1、節點目錄下有子節點,則父節點不能刪除------父節點不能刪除
2、如果節點是在/目錄下且該節點沒有子節點,不管有沒有刪除權限,任何的授權或者未授權用戶都能刪除該節點------根節點若沒有子節點可以隨便刪除
3、如果該節點上一層且只能是上一層父節點,沒有刪除權限,則該節點不能被刪除------本節點的父節點沒有被刪除的權限,則該節點也不能刪除

5-1 zookeeper集羣搭建

zk集羣,主從節點,心跳機制(選舉模式)

zookeeper集羣搭建注意點

1.配置數據文件myid1/2/3對應server.1/2/3
2.通過./zkCli.sh -server [ip]:[port]檢測集羣是否配置成功

5-2 單機僞分佈式集羣

單機的意思是在一臺服務器上創建多個zookeeper節點,ip不見端口不一

創建額外的兩個zookeeper節點

cp zookeeper zookeeper01 -rf
cp zookeeper zookeeper02 -rf

修改配置文件
/usr/local/zookeeper/conf/zoo.cfg

vim /usr/local/zookeeper/conf/zoo.cfg
dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid
1

/usr/local/zookeeper01/conf/zoo.cfg

vim /usr/local/zookeeper01/conf/zoo.cfg
dataDir=/usr/local/zookeeper01/dataDir
dataLogDir=/usr/local/zookeeper01/dataLogDir
clientPort=2182
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid
2

/usr/local/zookeeper02/conf/zoo.cfg

vim /usr/local/zookeeper02/conf/zoo.cfg
dataDir=/usr/local/zookeeper02/dataDir
dataLogDir=/usr/local/zookeeper02/dataLogDir
clientPort=2183
server.1=192.168.227.128:2888:3888
server.2=192.168.227.128:2889:3889
server.3=192.168.227.128:2890:3890

添加配置文件myid

vim /usr/local/zookeeper/conf/myid
3

節點創建配置完畢之後歐需要依次啓動三個節點的zookeeper服務器

cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2181
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2182
cd /usr/local/zookeeper01/bin
./zkServer.sh -server 192.168.227.128:2183

驗證集羣是否配置成功:

在一個zookeeper端口創建一個節點/team在另一個zookeeper端口查看是否存在這個節點/team,如果存在就代表配置成功

5-3 三臺物理機(虛擬機)安裝zookeeper

需要克隆三臺虛擬機
將serveer的ip和端口替換即可
zoo.cfg都替換如下列屬性

dataDir=/usr/local/zookeeper/dataDir
dataLogDir=/usr/local/zookeeper/dataLogDir
clientPort=2181
server.1=192.168.227.131:2888:3888
server.2=192.168.227.132:2888:3888
server.3=192.168.227.133:2888:3888

6-1 客戶端與zk服務器的連接& zk會話重連機制

連不上

//zookeeper的地址
public static final String zkAddress = "192.168.227.131:2181";
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zk = new ZooKeeper(zkAddress, 2000, new Watcher() {   
        @Override    
        public void process(WatchedEvent watchedEvent) 
        {       
            System.out.println("watcher事件:" + watchedEvent.getState().toString());
        }
    });
    long sessionId = zk.getSessionId();
    byte[] sessionPwd = zk.getSessionPasswd();
    System.out.println("與zookeeper正在連接:" + zk.getState());
    //連接過程需要時間
    Thread.sleep(2000);
    System.out.println("與zookeepeer連接成功:" + zk.getState());
    //zk會話重連
    zk = new ZooKeeper(zkAddress, 2000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {}
        }, sessionId, sessionPwd);
    System.out.println("與zookeeper正在連接:" + zk.getState());
    Thread.sleep(2000);
    System.out.println("與zookeepeer重連成功:" + zk.getState());
}

//控制檯打印
與zookeeper正在連接:CONNECTING
watcher事件:SyncConnected
與zookeepeer連接成功:CONNECTED
watcher事件:Closed
zk狀態:CLOSED
與zookeepeer開始重連...
與zookeeper正在連接:CONNECTING
與zookeepeer重連成功:CONNECTED

如果連接不上zookeeper:請關閉虛擬機防火牆,再次連接
systemctl stop firewalld.service

6-2 創建節點

同步創建:zk.create(path, data, acl, CreateMode);
異步創建:zk.create(path, data, acl, CreateMode, CallBack, ctx);

acl:控制權限策略
Ids.OPEN_ACL_UNSAFE–>world:anyone:crawd
CREATOR_ALL_ACL–>auth:user:password:crawd

CreateMode:節點類型:是一個枚舉
PRESISTENT:持久節點
PRESISTENT_SEQUENTIAL:持久順序節點
EPHEMERAL:臨時節點
EPHEMERAL_SEQUENTIAL:臨時順序節點


//同步創建
zk.create("/java", "java".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, 
CreateMode.PERSISTENT);
//異步創建
zk.create("/sys_java", "sys_java".getBytes(), 
ZooDefs.Ids.OPEN_ACL_UNSAFE,        CreateMode.PERSISTENT, new MyCallBack(), ctx);
//執行回調函數需要時間
Thread.sleep(2000);

6-3 修改節點數據

同步方式
setData(path, data, version)
異步方式
setData(path, data, version, CallBack, ctx)

6-4 刪除節點

同步方式
delete(path, data, version)
異步方式
delete(path, data, version, CallBack, ctx)

6-5 CountDownLatch的介紹

線程中的計數器
分佈式鎖中的計數器

  1. 它是一個計數器,可以累減
  2. 多用於線程,樂意暫停也可以繼續
  3. .await() .CountDown()

6-6 節點查詢

//節點查詢有同步查詢有異步查詢,在這裏討論的是同步查詢,異步查詢只不過有個回調函數,返回一些需要的數據,可以自己試試看
//父節點查詢
ZooKeeperServer zooKeeperServer = new ZooKeeperServer(addressPath);
//true表示再次添加watcher監聽,false爲不在添加
byte[] data = zooKeeperServer.getZooKeeperServer().getData("/java", false, stat);
String info = new String(data);
System.out.print(info);

//子節點查詢
List<String> nodeList = zookeeper.getZookeeperServer().getChildren("/java",false,stat);
for(String nodeName : nodeList) {
    System.out.print(nodeName);   
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章