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

02-zookeeper分布式鎖案例

這篇具有很好參考價值的文章主要介紹了02-zookeeper分布式鎖案例。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

1 Zookeeper分布式案例

1.1 Zookeeper分布式鎖原理

核心思想:當(dāng)客戶端要獲取鎖,則創(chuàng)建節(jié)點(diǎn),使用完鎖,則刪除該節(jié)點(diǎn)。

當(dāng)我們假設(shè)根節(jié)點(diǎn)/ 下有/locks節(jié)點(diǎn)時

1)客戶端獲取鎖時,在locks節(jié)點(diǎn)下創(chuàng)建臨時順序節(jié)點(diǎn)。

2)然后獲取lock下面的所有子節(jié)點(diǎn),客戶端獲取到所有的子節(jié)點(diǎn)之后,如果發(fā)現(xiàn)自己創(chuàng)建的子節(jié)點(diǎn)序號最小,那么就認(rèn)為該客戶端獲取到了鎖。(即需要小的優(yōu)先)使用完鎖后,將刪除該結(jié)點(diǎn)。

3)如果發(fā)現(xiàn)自己創(chuàng)建的節(jié)點(diǎn)并非locks所有子節(jié)點(diǎn)中最小的,說明自己還沒獲取到鎖,此時客戶端需要找到比自己小的那個節(jié)點(diǎn),同時對其注冊事件監(jiān)聽器,監(jiān)聽刪除事件。

4)如果發(fā)現(xiàn)比自己小的那個節(jié)點(diǎn)被刪除,則客戶端的Watcher會收到相應(yīng)通知,此時再次判斷自己創(chuàng)建的節(jié)點(diǎn)是否是locks子節(jié)點(diǎn)中序號最小的,如果是則獲取到了鎖,如果不是則重復(fù)以上步驟繼續(xù)獲取到比自己小的一個節(jié)點(diǎn)并注冊監(jiān)聽。

1.2 分布式鎖案例分析

  • 客戶端獲取到鎖時創(chuàng)建臨時順序節(jié)點(diǎn) create -e -s /locks/seq-
  • 接收到請求后,在/locks節(jié)點(diǎn)下創(chuàng)建一個臨時順序節(jié)點(diǎn)
  • 判斷自己是不是當(dāng)前節(jié)點(diǎn)下最小的節(jié)點(diǎn),如果是,獲取到鎖;如果不是,對前一個節(jié)點(diǎn)進(jìn)行監(jiān)聽
  • 獲取到鎖,處理完業(yè)務(wù)以后,delete節(jié)點(diǎn)釋放鎖,然后下面的節(jié)點(diǎn)將會收到通知,重復(fù)上述判斷

1.2.1 原生Zookeeper實(shí)現(xiàn)代碼實(shí)現(xiàn)

package com.clear.case2;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 分布式鎖案例
 */
public class DistributedLock {
    private final String connectString = "kk01:2181,kk02:2181,kk01:2181";
    private final int sessionTimeout = 2000;
    private final ZooKeeper zk;

    private CountDownLatch countDownLatch = new CountDownLatch(1);
    private CountDownLatch waitLatch = new CountDownLatch(1);

    private String waitPath;
    private String currentMode;

    public DistributedLock() throws IOException, InterruptedException, KeeperException {
        // 獲取連接
        zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                //  countDownLatch 如果連接上zk,可以釋放
                if (event.getState() == Event.KeeperState.SyncConnected) {
                    countDownLatch.countDown();
                }
                // waitLatch 可以釋放
                if (event.getType() == Event.EventType.NodeDeleted && event.getPath().equals(waitPath)) {
                    waitLatch.countDown();
                }
                System.out.println("");
            }
        });

        // 等待zk正常連接后再執(zhí)行后續(xù)程序
        countDownLatch.await();

        // 判斷根節(jié)點(diǎn)/locks是否存在
        Stat stat = zk.exists("/locks", false);
        if (stat == null) {
            // 創(chuàng)建根節(jié)點(diǎn)(根節(jié)點(diǎn)為持久節(jié)點(diǎn))
            zk.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    }

    // 對zk加鎖
    public void zkLock() {
        // 創(chuàng)建對應(yīng)的臨時帶序號的節(jié)點(diǎn)
        try {
            currentMode = zk.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            // 判斷創(chuàng)建的節(jié)點(diǎn)是否是根目錄下最小節(jié)點(diǎn),如果是獲得鎖;如果不是,監(jiān)聽它序號前一個節(jié)點(diǎn)
            List<String> children = zk.getChildren("/locks", false);
            // 如果children只有一個值,那就直接獲取鎖,如果有多個節(jié)點(diǎn),那就需要判斷誰最小
            if (children.size() == 1) {
                return;
            } else {
                Collections.sort(children);

                // 獲取節(jié)點(diǎn)名稱 seq-0000...
                String thisNode = currentMode.substring("/locks/".length());
                // 通過 seq-0000... 獲取其在集合children 中的位置
                int index = children.indexOf(thisNode);

                // 判斷
                if (index == -1) {
                    System.out.println("數(shù)據(jù)異常");
                } else if (index == 0) {
                    // 就一個節(jié)點(diǎn),獲取到了鎖
                    return;
                } else {
                    // 監(jiān)聽它前一個節(jié)點(diǎn)
                    waitPath = "/locks/" + children.get(index - 1);
                    zk.getData(waitPath, true, null);

                    // 等待監(jiān)聽
                    waitLatch.await();

                    return;
                }

            }

        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    // 對zk解鎖
    public void unZkLock() {
        // 刪除節(jié)點(diǎn)
        try {
            zk.delete(currentMode, -1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }
}

1.2.2 測試代碼

package com.clear.case2;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 分布式鎖案例
 */
public class DistributedLockTest {
    public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
        final DistributedLock lock1 = new DistributedLock();
        final DistributedLock lock2 = new DistributedLock();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.zkLock();
                    System.out.println("線程1 啟動,獲取到鎖");
                    Thread.sleep(5000);
                    lock1.unZkLock();
                    System.out.println("線程1 釋放鎖");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.zkLock();
                    System.out.println("線程2 啟動,獲取到鎖");
                    Thread.sleep(5000);
                    lock2.unZkLock();
                    System.out.println("線程2 釋放鎖");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

啟動后,結(jié)果如下

線程1 啟動,獲取到鎖
線程1 釋放鎖

線程2 啟動,獲取到鎖
線程2 釋放鎖

兩個線程不會同時得到鎖,此致,分布式鎖案例完成

1.2.3 Curator 框架實(shí)現(xiàn)分布式案例

1)原生的 Java API 開發(fā)存在的問題

  • 會話連接是異步的,需要自己去處理,比如使用 CountDownLatch
  • Watch 需要重復(fù)注冊,不然就不能生效
  • 開發(fā)的復(fù)雜性還是比較高的
  • 不支持多節(jié)點(diǎn)刪除和創(chuàng)建。需要自己去遞歸

2)Curator是一個專門解決分布式鎖的框架,解決了原生Java API 開發(fā)分布式遇到的問題

Cutator官方文檔 https://curator.apache.org/index.html

1、導(dǎo)入依賴

<!-- curator-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-client</artifactId>
            <version>4.0.0</version>
        </dependency>

2、代碼實(shí)現(xiàn)

package com.clear.case3;

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 org.apache.log4j.Logger;

public class CuratorLockTest {
    private final static Logger logger = Logger.getLogger(CuratorLockTest.class);

    public static void main(String[] args) {
        // 創(chuàng)建分布式鎖1
        InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");

        // 創(chuàng)建分布式鎖2
        InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework(), "/locks");

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock1.acquire();
                    System.out.println("線程1 獲取到鎖");
                    lock1.acquire();
                    System.out.println("線程1 再次獲取到鎖");

                    Thread.sleep(5000);
                    lock1.release();
                    System.out.println("線程1 釋放鎖");

                    lock1.release();
                    System.out.println("線程1 再次釋放鎖");

                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lock2.acquire();
                    System.out.println("線程2 獲取到鎖");
                    lock2.acquire();
                    System.out.println("線程2 再次獲取到鎖");

                    Thread.sleep(5000);
                    lock2.release();
                    System.out.println("線程2 釋放鎖");

                    lock2.release();
                    System.out.println("線程2 再次釋放鎖");

                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }
        }).start();
    }

    private static CuratorFramework getCuratorFramework() {
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("kk01:2181,kk02:2181,kk03:2181")
                .connectionTimeoutMs(2000)
                .sessionTimeoutMs(2000)
                .retryPolicy(new ExponentialBackoffRetry(3000, 3))
                .build();

        // 啟動客戶端
        client.start();

        logger.info("zookeeper啟動成功");
        return client;
    }
}

結(jié)果如下文章來源地址http://www.zghlxwxcb.cn/news/detail-698626.html

線程2 獲取到鎖
線程2 再次獲取到鎖
線程2 釋放鎖
線程2 再次釋放鎖
線程1 獲取到鎖
線程1 再次獲取到鎖

到了這里,關(guān)于02-zookeeper分布式鎖案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • ZooKeeper的分布式鎖

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

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

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

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

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

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

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

    2024年02月02日
    瀏覽(29)
  • 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)
  • 分布式鎖解決方案_Zookeeper實(shí)現(xiàn)分布式鎖

    提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動添加 分布式鎖解決方案_Zookeeper實(shí)現(xiàn)分布式鎖 提示:寫完文章后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 提示:這里可以添加本文要記錄的大概內(nèi)容: Zookeeper 是一個開源的分布式協(xié)調(diào)服務(wù),它

    2024年02月03日
    瀏覽(17)
  • 基于zookeeper實(shí)現(xiàn)分布式鎖

    基于zookeeper實(shí)現(xiàn)分布式鎖

    目錄 zookeeper知識點(diǎn)復(fù)習(xí) 相關(guān)概念 java客戶端操作 實(shí)現(xiàn)思路分析? 基本實(shí)現(xiàn) 初始化鏈接 代碼落地? 優(yōu)化:性能優(yōu)化 ?實(shí)現(xiàn)阻塞鎖 監(jiān)聽實(shí)現(xiàn)阻塞鎖 優(yōu)化:可重入鎖 zk分布式鎖小結(jié)? Zookeeper(業(yè)界簡稱zk)是一種提供配置管理、分布式協(xié)同以及命名的中心化服務(wù),這些提供的 功

    2024年02月02日
    瀏覽(17)
  • 4、Zookeeper分布式安裝部署

    1、分布式安裝部署 1)集群規(guī)劃 在hadoop102、hadoop103和hadoop104三個節(jié)點(diǎn)上部署Zookeeper。 服務(wù)器hadoop102 服務(wù)器hadoop103 服務(wù)器hadoop104 Zookeeper Zookeeper Zookeeper Zookeeper 2)解壓安裝 (1)解壓Zookeeper安裝包到/opt/module/目錄下 ?(2)修改/opt/module/apache-zookeeper-3.5.7-bin名稱為zookeeper 3)配

    2024年02月12日
    瀏覽(29)
  • zookeeper —— 分布式服務(wù)協(xié)調(diào)框架

    zookeeper —— 分布式服務(wù)協(xié)調(diào)框架

    Zookeeper是一個開源的分布式的,為分布式應(yīng)用提供協(xié)調(diào)服務(wù)的Apache項目。 Zookeeper從設(shè)計模式角度來理解:是一個基于觀察者模式設(shè)計的分布式服務(wù)管理框架,它負(fù)責(zé)存儲和管理大家都關(guān)心的數(shù)據(jù),然后接受觀察者的注冊,一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就將負(fù)責(zé)通知已

    2024年02月07日
    瀏覽(25)
  • 使用ZooKeeper實(shí)現(xiàn)分布式鎖

    目錄 引言 1. ZooKeeper簡介 2. 分布式鎖實(shí)現(xiàn)原理 3. 分布式鎖實(shí)現(xiàn)步驟 步驟一:創(chuàng)建ZooKeeper客戶端 步驟二:創(chuàng)建分布式鎖類 步驟三:使用分布式鎖 4. 總結(jié) 在分布式系統(tǒng)中,實(shí)現(xiàn)分布式鎖是一項常見的任務(wù),可以用于保證同一時間只有一個客戶端可以訪問共享資源,從而避免競

    2024年02月21日
    瀏覽(20)
  • 分布式【Zookeeper ZAB協(xié)議】

    分布式【Zookeeper ZAB協(xié)議】

    1.1 什么是Zab協(xié)議? Zab協(xié)議的全稱是 Zookeeper Atomic Broadcast (Zookeeper原子廣播)。 Zookeeper 是通過 Zab 協(xié)議來保證分布式事務(wù)的最終一致性 。 Zab協(xié)議是為分布式協(xié)調(diào)服務(wù)Zookeeper專門設(shè)計的一種 支持崩潰恢復(fù) 的 原子廣播協(xié)議 ,是Zookeeper保證數(shù)據(jù)一致性的核心算法。Zab借鑒了Pa

    2024年02月03日
    瀏覽(30)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包