1. 程式人生 > 其它 >Java連線Zookeeper以及書寫簡單增刪改查的方法

Java連線Zookeeper以及書寫簡單增刪改查的方法

Java連線Zookeeper以及書寫簡單增刪改查的方法

  摘要:本筆記主要記錄了使用IDEA建立一個Maven專案並使用Maven配置檔案下載Zookeeper連線驅動,連線雲伺服器的Zookeeper服務並書寫一些簡單的增刪改查方法的過程

目錄

1.建立Maven專案

  Maven是什麼?Maven實際上是一個專案管理工具,Maven分為Maven倉庫和Maven命令兩部分,其中Maven倉庫是存放各種jar包驅動各種外掛的地方,這裡存放了所有我們在構建專案過程中可能用到的jar包,Maven命令是Maven中帶有的一些指令碼操作,這些命令將我們在專案構建過程中的一些操作進行了打包,比如我們在一個專案完成,將這個專案製作成一個war包或者jar包的時候,需要很多操作,才能讓它變成一個合法的war包或jar包並進行最終的部署,但是使用Maven我們可以一鍵完成這個過程,鑑於我自己也是在初學Maven,很多東西的認知比較淺,對於Maven目前也是止步於建立並簡單的使用Maven專案,因此在這裡不再進行過多的解釋,我們目前階段只須記住:Maven可以管理jar包,Maven專案中可以使用配置檔案讓Maven自動的下載我們想要的jar包並完成自動匯入,不需要我們親自在網上找並手動匯入,方便了我們的操作

。接下來,讓我們嘗試著建立一個Maven專案:

  我們新建一個Maven專案,至於模板我們可以不選,操作出如上介面後我們直接點選next即可,

  我們起一個名字,然後點選finish就可以了,成功後如下圖所示,我們直接進入了pom配置檔案,我們使用該檔案可以進行配置:

  我們先將該專案的Maven路徑修改成自己的,並將Maven配置檔案也修改成自己的,這裡是因為idea自帶的Maven中的配置的Maven倉庫地址是一個外網地址,我們一般的網路訪問不到,可能會出現由於下載不了jar包而導致專案一直報錯的情況,我在下載Maven的時候,已經將其中的配置檔案進行了修改,將Maven倉庫的映象改成了阿里巴巴的映象,這樣一來我們就可以下載各種jar包了,因此在idea中我們需要將Maven的路徑改成自己的,配置檔案也要修改成自己的,具體操作如下圖所示:

  首先我們點選file,然後選擇setting,就會出現如圖所示的視窗,之後我們可以在藍色箭頭的搜尋欄中搜索Maven,然後直接就會跳轉到Maven配置的介面,按照圖中提示,我們可以進行相應的配置,配置完成後如圖所示:

  紅框中的兩個位置都要修改成自己的,之後點選確認即可。萬事大吉後,我們就可以修改pom檔案,讓Maven自動為我們下載連結Zookeeper的啟動就好了。我們在pom檔案的properties標籤的後邊加入下面的配置資訊:

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

  程式碼如上圖所示,加入配置資訊之後,idea就會自動下載zookeeper的相關控制jar包,我們現在可以發現在擴充套件目錄下,jar包已經被下載好了,如圖所示:

  至此,支援連線zookeeper的環境就搭建好了,我們現在就可以書寫連線zookeeper以及控制zookeeper的方法了。

2.Zookeeper的連線操作

  首先我們建立一個測試各種方法的類,如圖所示:

  之後我們先要在類中定義兩個重要欄位,其中一個是提供zookeeper服務的伺服器地址欄位,一個是超時時間欄位,伺服器地址欄位是幹啥用的不必多說,超時時間的含義是一旦連線服務的時間超過了所設定的時間,就會認定為連線失敗並終止這個連線操作,我們定義欄位如下:

public static final String serverAddress = "XXX.XXX.XXX.XXX:YYYY";
public static final int timeout = 15000;

  其中serverAddress是服務地址,XXX部分是伺服器公網地址,YYYY部分是zookeeper服務的埠,這個埠通常來說是2181,我們也可以通過配置檔案將其修改成自己想要的埠。之後我們就可以書寫zookeeper的連線方法了,如下圖所示:

  建立zookeeper連線的方式很簡單,就是使用Zookeeper的構造方法,輸入引數:服務地址超時時間,然後建立一個物件即可,但是我們發現這裡報錯了,這是因為在Zookeeper的jar包原始碼中,在Zookeeper的形參列表為服務地址和超時時間的構造器中丟擲了一個異常,為什麼丟擲這個異常呢?因為這種遠端連線的建立不是100%成功的,因此在這裡丟擲了一個IO異常,現在讓我們來看看原始碼:

  我們可以發現這些構造器中均丟擲了IO異常,因此在我們的程式碼這裡可以選擇繼續丟擲,也可以選擇做一個try/catch操作,這裡我做一個try/catch操作。如圖所示:

  這樣一來就不會報錯了,在這裡我們不僅可以使用try/catch的操作,還可以使用在方法體上直接丟擲這個異常,讓更上一層的呼叫者去處理這個異常,這種方法是在方法體上新增throws關鍵詞,兩種方法都可以,下面附上我的程式碼:

	/**
     * @description:
     * @param
     * @return: org.apache.zookeeper.ZooKeeper
     * @author: 李若白
     * @time: 4/5/2022 5:32 PM
     */
    public static ZooKeeper connect(){
        System.out.println("開始獲取zookeeper連線...");
        ZooKeeper zk = null;
        try {
            zk = new ZooKeeper(serverAddress,timeout,null);
            System.out.println("獲取連線成功!");
            return zk;
        } catch (IOException e) {
            System.out.println("獲取連線時出現異常,請重試...");
            e.printStackTrace();
            return null;
        }
    }

  我們試執行一下:

  連線成功!

3.Zookeeper的新增操作

  接下來我們書寫新增操作,首先我們確定框架如下,zkConnect是我們剛獲取的連線,node是我們選定的zookeeper節點,data是我們想要插入的zookeeper資料:

  之後我們要根據zookeeper驅動中提供的方法,建立一個節點並將這個節點放入到zookeeper的儲存結構中去,我們書寫程式碼如下:

  其中acl變數指的是節點許可權,我們進入原始碼中可以發現:

  Ids下有這麼幾個不同的許可權,我們在穿件Zookeeper節點的時候,需要為其賦予許可權,這些許可權的資訊就存在這裡,這些許可權的含義為:

OPEN_ACL_UNSAFE:完全開放的ACL,任何連線的客戶端都可以操作該屬性znode
CREATOR_ALL_ACL:只有建立者才有ACL許可權
READ_ACL_UNSAFE:只能讀取ACL

  之後我們繼續書寫程式碼,我們之後又加入一行:

  新的一行程式碼的含義是節點型別,這個節點型別資訊同樣在原始碼中可以看到,如下:

  節點型別一共有四種,介紹如下:

PERSISTENT:永續性的節點,目錄不會丟失
PERSISTENT_SEQUENTAL:儲存的資料不會丟失,並且根據當前已經存在的節點數目自動加1,然後返回給客戶端已經成功建立的目錄節點名
EPHEMERAL:臨時目錄節點,一旦建立這個節點的客戶端與伺服器埠也就是session超時,這種節點就會被刪除
EPHEMERAL_SEQUENTAL:臨時自動編號節點,一旦建立這個節點的客戶端與伺服器埠也就是session超時,這種節點就會被刪除

  現在我們許可權也有了,型別也有了,資料也有了,就要建立節點了,我們繼續書寫程式碼:

  這個create也是有原始碼的,我們去看看:

  我們發現自己書寫的程式碼在data出報錯,這是因為在原始碼中,data應該是byte[]型別的,而非String型別,同時我們還發現了create方法要丟擲兩個異常,在之後的書寫中我們要注意,我們首先將data處的錯誤解決:

  如圖所示我已經將所有問題解決了,接下來我們可以測試看看:

  可見客戶端已經提示建立成功,我們接下來在伺服器上看看是否真的已經建立成功:

  可見確實已經建立成功了,下面我附上程式碼:

	/**
     * @description:
     * @param zkConnect zookeeper連線
     * @param node 我們選定的zookeeper節點
     * @param data 我們想要插入的資料
     * @return: void
     * @author: 李若白
     * @time: 4/5/2022 5:57 PM
     */
    public static void create(ZooKeeper zkConnect,String node,String data){
        System.out.println("開始建立節點:"+node+",節點資料為:"+data);
        List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;//這個引數是節點許可權,在Zookeeper中每個節點有各自的許可權,我們使用acl並變數儲存許可權
        CreateMode createMode = CreateMode.PERSISTENT;//這個引數是節點型別
        try {
            zkConnect.create(node,data.getBytes(),acl,createMode);
            System.out.println("建立成功!");
        } catch (KeeperException e) {
            System.out.println("建立失敗!");
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println("建立失敗!");
            e.printStackTrace();
        }
    }

4.Zookeeper的刪除操作

  接下來我們書寫刪除操作,有了上面新增的先例,我們就有做刪除方法的經驗了,和新增一樣,在Zookeeper的原始碼中也是存在基礎的刪除操作呼叫的,如圖所示:

  在原始碼中的刪除方法中顯示其擁有兩個引數,其中一個引數叫path,顧名思義,這個引數實際上就是節點的路徑,那version是什麼呢?version的中文意思是版本,那麼為什麼刪除需要版本,這個版本又是誰的版本呢?這個版本號是zookeeper節點的版本號,在zookeeper中每一個節點都有一個自己的版本號,當我們將版本號引數設定為-1的時候,含義為無視版本號,那這個版本號具有有什麼作用呢?有一種叫做CAS的概念,在作業系統以及併發程式設計中存在這個概念,此概念的含義為比較並交換,其內部有一個很重要的觀念,就是版本號的觀念,版本號的加入是為了併發時的安全所設定,目前由於我並沒有學習到這個程度,因此僅僅瞭解到版本號是CAS中的一個觀念,目的是為了併發時的安全即可。

  既然知道了zookeeper中的節點有版本號,那我們就需要想辦法獲取版本號,接下來我們看程式碼:

  想要刪除一個節點,首先要確認zookeeper的儲存結構中有沒有這個節點,因此我們首先用exists進行判斷,如果有的話,那麼exists這個方法就不會丟擲異常,並返回該節點的資訊,其中該節點的版本資訊就存放在了這個返回資訊中,我們可以根據這個返回資訊來獲取當前該節點正確的版本號,進而進行刪除操作,接下來我們測試一下:

  我們在服務端看一看是否還有這個節點:

  刪除成功!在下邊我附上程式碼:

	/**
     * @description:
     * @param zkConnect
     * @param node
     * @return: void
     * @author: 李若白
     * @time: 4/5/2022 10:14 PM
     */
    public static void delete(ZooKeeper zkConnect,String node){
        try {
            Stat stat = zkConnect.exists(node,false);
            System.out.println("開始刪除節點:"+node);
            zkConnect.delete(node,stat.getVersion());
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

5.Zookeeper的修改操作

  接下來我們書寫修改操作,有了刪除操作的經驗,我們書寫修改操作就可以變得很容易了,我們首先檢視原始碼:

  除去一些必要的因素,我們注意到了在set操作中有一個data引數,這個引數是我們想要為該節點設定的新值,因此我們可以自己書寫程式碼如下:

  邏輯同樣是先判斷是否存在節點,之後呼叫驅動中的方法進行值的更新,這裡測試結果不再展示,自測成功,下面附上程式碼:

	/**
     * @description:
     * @param zkConnect
     * @param node
     * @param data
     * @return: void
     * @author: 李若白
     * @time: 4/5/2022 10:19 PM
     */
    public static void setNode(ZooKeeper zkConnect,String node,String data) throws InterruptedException, KeeperException {
        Stat stat = zkConnect.exists(node,false);
        zkConnect.setData(node,data.getBytes(),stat.getVersion());
        System.out.println("新值設定成功!");
           
        
    }

6.Zookeeper的查詢操作

  接下來我們書寫查詢操作,查詢操作的邏輯同上,僅展示程式碼:

  下面附上程式碼:

	/**
     * @description:
     * @param zooKeeper
     * @param node
     * @return: void
     * @author: 李若白
     * @time: 4/5/2022 10:23 PM
     */
    public static void getNode(ZooKeeper zooKeeper,String node) throws InterruptedException, KeeperException {
        Stat stat = zooKeeper.exists(node,false);
        String info = new String(zooKeeper.getData(node,false,stat));
    }