欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ZooKeeper命令及JavaAPI操作代碼

 更新時間:2023年03月14日 10:29:58   作者:你的肩上有片楓葉  
ZooKeeper是一個樹形目錄服務(wù),其數(shù)據(jù)模型和Uiix的文件目錄樹很類似,擁有一個層次化結(jié)構(gòu),這篇文章主要介紹了ZooKeeper命令及JavaAPI操作代碼,需要的朋友可以參考下

ZooKeeper數(shù)據(jù)模型

  • ZooKeeper是一個樹形目錄服務(wù),其數(shù)據(jù)模型和Uiix的文件目錄樹很類似,擁有一個層次化結(jié)構(gòu)。
  • 這里面的每一個節(jié)點都被稱為:ZNode,每個節(jié)點上都會保存自己的數(shù)據(jù)和節(jié)點信息。
  • 節(jié)點可以擁有子節(jié)點,同時也允許少量(1MB)數(shù)據(jù)存儲在該節(jié)點之下。
  • 節(jié)點可以分為四大類:
    • PEFSISTENT持久化節(jié)點
    • EPHEMERAL臨時節(jié)點:-e
    • PERSISTENT_SEQUENTIAL持久化順序節(jié)點:-s
    • EPHEMERAL_SEQUENTIAL臨時順序節(jié)點:-es

ZooKeeper服務(wù)端常用命令

  • 啟動ZooKeeper服務(wù):./zkServer.sh start
  • 查看ZooKeeper服務(wù):./zkServer.sh status
  • 停止ZooKeeper服務(wù):./zkServer.sh stop
  • 重啟ZooKeeper服務(wù):./zkServer.sh restart

ZooKeeper客戶端命令

  • ./zkCli.sh -server localhost:2181連接服務(wù)端,如果是單機后面的可以省略不寫。
  • ls [/] :查看指定節(jié)點下子節(jié)點
  • create [/app] [hrbu]:創(chuàng)建一個名為/app1的子節(jié)點,并存放數(shù)據(jù)。
  • get [/app] :獲取節(jié)點下的數(shù)據(jù)。
  • set [/app] [hrbu]:給指定節(jié)點設(shè)置數(shù)據(jù)
  • delete [/app] :刪除指定節(jié)點 ps:此命令無法刪除存在子節(jié)點的節(jié)點,如果要刪除帶有子節(jié)點的節(jié)點可以是使用deleteall [/app] 命令。
  • quit 斷開連接
  • help 查看命令幫助
  • create -e [/app] 創(chuàng)建臨時節(jié)點,會話關(guān)閉就會刪除
  • create -s [/app] 創(chuàng)建順序節(jié)點
  • create -es [/app] 創(chuàng)建臨時順序節(jié)點
  • ls -s [/app] 查看節(jié)點的詳細信息

使用Curator API操作Zookeeper

建立連接

@Test
public void testConnect() {
    //重試策略
    ExponentialBackoffRetry retry = new ExponentialBackoffRetry(3000, 10);
    //第一種方式
    CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.130.120:2181", 60 * 1000, 15 * 1000, retry);

    //第二種方式
    CuratorFramework client1 = CuratorFrameworkFactory.builder().connectString("192.168.130.120:2181")
        .sessionTimeoutMs(60 * 1000)
        .connectionTimeoutMs(15 * 1000)
        .retryPolicy(retry).namespace("hrbu").build();
    //開啟連接
    client.start();
}

參數(shù)解讀

  • connectString – list of servers to connect to (ZooKeeper的地址)

sessionTimeoutMs – session timeout (會話超時時間)
connectionTimeoutMs – connection timeout (連接超時時間)
retryPolicy – retry policy to use (重試策略)

在這里插入圖片描述

會話超時時間和連接超時時間有默認值。

第二種鏈式編程的方式可以指定一個工作空間,在此客戶端下的所有操作都會將此工作空間作為根目錄。

注意

如果使用的是云服務(wù)器需要將指定端口打開

firewall-cmd --zone=public --add-port=2181/tcp --permanent 開放端口

firewall-cmd --zone=public --list-ports 查看已經(jīng)開放的端口

systemctl restart firewalld 重啟防火墻生效

最后別忘了在服務(wù)器的安全組里面添加端口,將2181端口打開

添加節(jié)點

@Test
public void testCreate1() throws Exception {
    //基本創(chuàng)建
    CreateBuilder createBuilder = client.create();
    //創(chuàng)建時不指定數(shù)據(jù),會將當前客戶端ip存到里面
    createBuilder.forPath("/app1");
    //指定數(shù)據(jù)
    createBuilder.forPath("/app2", "hello".getBytes());
}

@Test
public void testCreate2() throws Exception {
    CreateBuilder createBuilder = client.create();

    //設(shè)置節(jié)點類型,默認的類型是持久化
    //CreateMode是枚舉類型
    createBuilder.withMode(CreateMode.EPHEMERAL).forPath("/app3");
}

@Test
public void testCreate3() throws Exception {
    CreateBuilder createBuilder = client.create();
    //創(chuàng)建多級節(jié)點,如果父節(jié)點不存在,則創(chuàng)建父節(jié)點。
    createBuilder.creatingParentContainersIfNeeded().forPath("/app4/app4_1");
}

查詢節(jié)點

@Test
public void testGet() throws Exception {
    //查詢數(shù)據(jù)
    byte[] bytes = client.getData().forPath("/app1");
    System.out.println(new String(bytes));

    //查詢子節(jié)點
    List<String> strings = client.getChildren().forPath("/app4");
    strings.forEach(System.out::println);

    //查詢節(jié)點狀態(tài)信息
    Stat stat = new Stat();
    client.getData().storingStatIn(stat).forPath("/app1");
    System.out.println(stat);
}

修改節(jié)點

@Test
public void testSet() throws Exception {
    //修改數(shù)據(jù)
    client.setData().forPath("/app1","hrbu".getBytes());

    //根據(jù)版本修改
    int version  = 0;
    Stat stat = new Stat();
    client.getData().storingStatIn(stat).forPath("/app1");
    version = stat.getVersion();

    client.setData().withVersion(version).forPath("/app1", "HRBU".getBytes());
}

刪除節(jié)點

@Test
public void testDelete() throws Exception {
    //刪除單個節(jié)點
    client.delete().forPath("/app4/app4_1");

    //刪除帶有子節(jié)點的節(jié)點
    client.delete().deletingChildrenIfNeeded().forPath("/app4");

    //強制刪除
    client.delete().guaranteed().forPath("/app4");

    //回調(diào)
    client.delete().guaranteed().inBackground(new BackgroundCallback() {
        @Override
        public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
            System.out.println("執(zhí)行刪除操作");
        }
    }).forPath("/app4");

}

Watch事件監(jiān)聽

  • Zookeeper允許用戶在指定節(jié)點上注冊一些Watcher,并且在一些特定事件觸發(fā)的時候,ZooKeeper服務(wù)端會將事件通知到感興趣的客戶端上去,該機制是ZooKeeper實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。
  • ZooKeeper中引入了Watcher機制來實現(xiàn)了發(fā)布/訂閱功能,能夠讓多個訂閱者同時監(jiān)聽某一個對象,當一個對象自身狀態(tài)變化時,會通知所有訂閱者。
  • ZooKeeper原生支持通過注冊Watcher來進行事件監(jiān)聽,但是使用并不是特別方便,需要開發(fā)人員自己反復(fù)注冊Watcher,比較繁瑣。
  • Curator引入了Cache來時限對Zookeeper服務(wù)端事件的監(jiān)聽。
  • ZooKeeper提供了三種Watcher:
    • NodeCache:只是監(jiān)聽某一個特定的節(jié)點。
    • PathChildrenCache:監(jiān)控一個Node的子節(jié)點。
    • TreeCache:可以監(jiān)控整個樹上的所有節(jié)點,類似于PathChildrenCache和NodeCache的組合。

NodeCache

@Test
public void testNodeCache() throws Exception {
    //NodeCache:指定一個節(jié)點注冊監(jiān)聽器

    //創(chuàng)建NodeCache對象
    final NodeCache nodeCache = new NodeCache(client, "/app1");
    //注冊監(jiān)聽
    nodeCache.getListenable().addListener(new NodeCacheListener() {
        @Override
        public void nodeChanged() throws Exception {
            System.out.println("app1節(jié)點發(fā)生變化");

            //獲取修改節(jié)點后的數(shù)據(jù)
            byte[] data = nodeCache.getCurrentData().getData();
            System.out.println("變化后的節(jié)點:"+new String(data));
        }
    });
    //開啟監(jiān)聽,如果為true,則開啟則開啟監(jiān)聽,加載緩沖數(shù)據(jù)
    nodeCache.start(true);
}

PathChildrenCache

@Test
public void testPathChildrenCache() throws Exception {
    //PathChildrenCache:監(jiān)聽某個節(jié)點的所有子節(jié)點
    //創(chuàng)建監(jiān)聽對象
    PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/hrbu", true);

    //綁定監(jiān)聽器
    pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
        @Override
        public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
            System.out.println("子節(jié)點發(fā)生變化");
            System.out.println(pathChildrenCacheEvent);
            //監(jiān)聽子節(jié)點的數(shù)據(jù)變更,并且得到變更后的數(shù)據(jù)

            //獲取類型
            PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();

            //判斷類型
            if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)) {
                //獲取數(shù)據(jù)
                byte[] data = pathChildrenCacheEvent.getData().getData();
                System.out.println(new String(data));
            }
        }
    });

    //開啟
    pathChildrenCache.start();
}

TreeCache

@Test
public void testTreeCache() throws Exception {
    //創(chuàng)建監(jiān)聽器
    TreeCache treeCache = new TreeCache(client, "/");

    //注冊監(jiān)聽
    treeCache.getListenable().addListener(new TreeCacheListener() {
        @Override
        public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {
            System.out.println("節(jié)點發(fā)生變化");
            System.out.println(treeCacheEvent);
        }
    });

    //開啟
    treeCache.start();

}

分布式鎖實現(xiàn)

概述

  • 我們在進行單機應(yīng)用開發(fā),涉及并發(fā)同步的時候,,我們往往采用synchronized或者lock的方式來解決多線程間的代碼同步問題,這時候多線程的運行都是在同一個JVM之下,沒有任何問題。
  • 但當我們的應(yīng)用時分布式集群工作的情況下,屬于多JVM下的工作環(huán)境,跨JVM之間已經(jīng)無法通過多線程的鎖解決同步問題。
  • 那么就需要一種更加高級的鎖機制,來處理跨機器進程之間的數(shù)據(jù)同步問題,這就是分布式鎖。

Zookeeper分布式鎖原理

  • 核心思想:當客戶端要獲取鎖,則創(chuàng)建節(jié)點,使用完鎖,則刪除該節(jié)點。
    • 1.客戶端獲取鎖時,在lock節(jié)點下創(chuàng)建臨時順序節(jié)點。
    • 2.然后獲取lock下面的所有子節(jié)點,客戶端獲取到所有的子節(jié)之后,如果發(fā)現(xiàn)自己創(chuàng)建的子節(jié)點序號最小,那么就認為該客戶端獲取到了鎖。使用完鎖后,將該節(jié)點刪除。
    • 3.如果發(fā)現(xiàn)自己創(chuàng)建的節(jié)點并非lock所有子節(jié)點中最小的,說明自己還沒有獲取到鎖,此時客戶端需要找到比自己小的那個節(jié)點,同時對其注冊事件監(jiān)聽器,監(jiān)聽刪除事件。
    • 4.如果發(fā)現(xiàn)比自己小的那個節(jié)點被刪除,則客戶端的Watcher會收到相應(yīng)通知,此時再次判斷自己創(chuàng)建的節(jié)點是否時lock子節(jié)點中序號最小的,如果是則獲取到了鎖,如果不是則重復(fù)以上步驟繼續(xù)獲取比自己小的一個節(jié)點并注冊監(jiān)聽。

Curator實現(xiàn)分布式鎖API

在Curator中有五種鎖方案:

  • InterProcessSemaphoreMutex:分布式排它鎖(非可重入鎖)
  • InterProcessMutex:分布式可重入排它鎖
  • InterProcessReadWriteLock:分布式讀寫鎖
  • InterProcessMultiLock:將多個鎖作為單個實體管理的容器
  • InterProcessSemaphoreV2:共享信號量
package com.hrbu.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.concurrent.TimeUnit;

public class Ticket12306 implements Runnable{

    private int tickets = 10;//數(shù)據(jù)庫的票數(shù)

    private InterProcessMutex lock ;


    public Ticket12306(){
        //重試策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("8.130.32.75:2181")
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(15 * 1000)
                .retryPolicy(retryPolicy)
                .build();
        //開啟連接
        client.start();
        lock = new InterProcessMutex(client,"/lock");
    }

    @Override
    public void run() {

        while(true){
            //獲取鎖
            try {
                lock.acquire(3, TimeUnit.SECONDS);
                if(tickets > 0){
                    System.out.println(Thread.currentThread()+":"+tickets);
                    Thread.sleep(100);
                    tickets--;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                //釋放鎖
                try {
                    lock.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package com.hrbu.curator;
public class LockTest {
    public static void main(String[] args) {
        Ticket12306 ticket12306 = new Ticket12306();

        //創(chuàng)建客戶端
        Thread t1 = new Thread(ticket12306,"攜程");
        Thread t2 = new Thread(ticket12306,"飛豬");

        t1.start();
        t2.start();
    }
}

到此這篇關(guān)于ZooKeeper命令及JavaAPI操作的文章就介紹到這了,更多相關(guān)ZooKeeper JavaAPI操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java處理字節(jié)的常用工具類

    java處理字節(jié)的常用工具類

    這篇文章主要為大家詳細介紹了java處理字節(jié)的常用工具類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Mybatis Plus 增刪改查的實現(xiàn)(小白教程)

    Mybatis Plus 增刪改查的實現(xiàn)(小白教程)

    本文主要介紹了Mybatis Plus 增刪改查,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解決方案

    SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解決方案

    這篇文章主要介紹了SpringBoot2.0整合SpringCloud Finchley @hystrixcommand注解找不到解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • java實現(xiàn)傾斜水印鋪滿整張圖

    java實現(xiàn)傾斜水印鋪滿整張圖

    這篇文章主要為大家詳細介紹了java實現(xiàn)傾斜水印鋪滿整張圖的具體代碼,教大家如何控制水印之間的空隙,感興趣的小伙伴們可以參考一下
    2016-06-06
  • SpringBoot通過Filter實現(xiàn)整個項目接口的SQL注入攔截詳解

    SpringBoot通過Filter實現(xiàn)整個項目接口的SQL注入攔截詳解

    這篇文章主要介紹了SpringBoot通過Filter實現(xiàn)整個項目接口的SQL注入攔截詳解,SQL注入是比較常見的網(wǎng)絡(luò)攻擊方式之一,在客戶端在向服務(wù)器發(fā)送請求的時候,sql命令通過表單提交或者url字符串拼接傳遞到后臺持久層,最終達到欺騙服務(wù)器執(zhí)行惡意的SQL命令,需要的朋友可以參考下
    2023-12-12
  • 解決SpringBoot引用別的模塊無法注入的問題

    解決SpringBoot引用別的模塊無法注入的問題

    這篇文章主要介紹了解決SpringBoot引用別的模塊無法注入的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • PowerJob Alarmable工作流程源碼剖析

    PowerJob Alarmable工作流程源碼剖析

    這篇文章主要為大家介紹了PowerJob Alarmable工作流程源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • java Volatile與Synchronized的區(qū)別

    java Volatile與Synchronized的區(qū)別

    這篇文章主要介紹了java Volatile與Synchronized的區(qū)別,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • RestTemplate自定義請求失敗異常處理示例解析

    RestTemplate自定義請求失敗異常處理示例解析

    這篇文章主要為大家介紹了RestTemplate自定義請求失敗異常處理的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-03-03
  • Java如何替換字符

    Java如何替換字符

    文章介紹了Java中String類的replace()方法及其變體replaceFirst()的使用,包括如何替換單個字符、第一次出現(xiàn)的字符以及多個字符,通過示例展示了如何處理字符串中的特殊字符和空格
    2024-11-11

最新評論