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

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

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot基于Zookeeper實(shí)現(xiàn)分布式鎖。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

SpringBoot基于Zookeeper實(shí)現(xiàn)分布式鎖,Zookeeper,分布式,java-zookeeper,spring boot

問題背景

研究分布式鎖,基于ZK實(shí)現(xiàn),需要整合到SpringBoot使用

前言

  1. 參考自SpringBoot集成Curator實(shí)現(xiàn)Zookeeper基本操作,Zookeeper入門
  2. 本篇的代碼筆者有自己運(yùn)行過,需要注意組件的版本號(hào)是否兼容,否則會(huì)有比較多的坑

實(shí)現(xiàn)

搭建Zookeeper容器

采用Docker compose快速搭建ZK容器,很快,幾分鐘就好了,而且是集群方式搭建。詳情見筆者的Docker搭建zookeeper

引入依賴

需要注意的點(diǎn):Curator 2.x.x-兼容兩個(gè)zk 3.4.xzk 3.5.xCurator 3.x.x-兼容兼容zk 3.5,根據(jù)搭建的zk的版本使用對(duì)應(yīng)的curator依賴。引入的zk依賴,如果項(xiàng)目中有使用logback日志 ,需要排除zk中的log4j12依賴,詳情見下面筆者給出的依賴:

<dependencies>
  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-client</artifactId>
      <version>2.12.0</version>
  </dependency>

  <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>2.12.0</version>
  </dependency>

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

  <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.5.7</version>
      <exclusions>
          <exclusion>
              <artifactId>slf4j-log4j12</artifactId>
              <groupId>org.slf4j</groupId>
          </exclusion>
          <exclusion>
              <artifactId>slf4j-api</artifactId>
              <groupId>org.slf4j</groupId>
          </exclusion>
      </exclusions>
  </dependency>

ZK客戶端的配置類

配置ZK的參數(shù),使用@ConfigurationProperties可以令配置熱更新,比如搭配Apollo、Nacos,如果使用@Valid則無法熱更新,必須重啟項(xiàng)目才能生效

@Component
@ConfigurationProperties(prefix = "curator")
@Data
public class ZKClientProps {

    private String connectString;
    private int retryCount;
    private int elapsedTimeMs;
    private int sessionTimeoutMs;
    private int connectionTimeoutMs;
}

對(duì)應(yīng)yml如下:

#curator配置
curator:
  connectString: 192.168.163.128:2181,192.168.163.128:2182,192.168.163.128:2183 # zookeeper 地址
  retryCount: 1 # 重試次數(shù)
  elapsedTimeMs: 2000 # 重試間隔時(shí)間
  sessionTimeoutMs: 60000 # session超時(shí)時(shí)間
  connectionTimeoutMs: 10000 # 連接超時(shí)時(shí)間

ZK客戶端的工廠類

定制ZK客戶端:

@Component
public class ZKClientFactory {

    @Resource
    private ZKClientProps zkClientProps;
    public CuratorFramework createSimple() {
        //重試策略:第一次重試等待1S,第二次重試等待2S,第三次重試等待4s

        //第一個(gè)參數(shù):等待時(shí)間的基礎(chǔ)單位,單位為毫秒
        //第二個(gè)參數(shù):最大重試次數(shù)
        ExponentialBackoffRetry retry = new ExponentialBackoffRetry(zkClientProps.getElapsedTimeMs(), zkClientProps.getRetryCount());

        //獲取CuratorFramework示例的最簡(jiǎn)單方式
        //第一個(gè)參數(shù):zk的連接地址
        //第二個(gè)參數(shù):重試策略
        return CuratorFrameworkFactory.newClient(zkClientProps.getConnectString(), retry);
    }


    public static CuratorFramework createWithOptions(String connectionString, RetryPolicy retryPolicy,
                                                     int connectionTimeoutMs, int sessionTimeoutMs) {
        return CuratorFrameworkFactory.builder().connectString(connectionString)
                .retryPolicy(retryPolicy).connectionTimeoutMs(connectionTimeoutMs).sessionTimeoutMs(sessionTimeoutMs).build();
    }
}

注入bean

創(chuàng)建ZK的客戶端,詳情如下:

@Component
@Slf4j
public class ZKClient {

    @Resource
    private ZKClientFactory zkClientFactory;
    public static final ZKClient INSTANCE = new ZKClient();

    private ZKClient() {
    }

    public CuratorFramework getClient() {
        return zkClientFactory.createSimple();
    }

    public boolean isNodeExist(String path) {
        CuratorFramework client = getClient();
        try {
            client.start();
            Stat stat = client.checkExists().forPath(path);
            return stat != null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
        return false;
    }

    public void createNode(String path, byte[] bytes) {
        CuratorFramework client = getClient();
        try {
            // 必須start,否則報(bào)錯(cuò)
            client.start();
            client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, bytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    public void deleteNode(String path) {
        CuratorFramework client = getClient();
        try {
            client.start();
            client.delete().forPath(path);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseableUtils.closeQuietly(client);
        }
    }

    public List<String> getChildren(String path) {
        List<String> result = new LinkedList<>();
        CuratorFramework client = getClient();
        try {
            client.start();
            result = client.getChildren().forPath(path);
        } catch (Exception e) {
            log.error("ZKClient getChildren error.");
        }
        return result;
    }

}

構(gòu)建測(cè)試類

測(cè)試基類,設(shè)置激活環(huán)境

@Slf4j
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = GmallZookeeperApplication.class)
@ContextConfiguration
public class BaseTest {

}

創(chuàng)建節(jié)點(diǎn)、刪除節(jié)點(diǎn)、獲取節(jié)點(diǎn)信息、分布式鎖的方法如下:@ActiveProfiles("company")是激活筆者一個(gè)application-company.yml文件

application.yml如下:

server:
  port: 8022

spring:
  profiles:
    active: home

application-compay.yml如下:

#curator配置
curator:
  connectString: 192.168.163.128:2181,192.168.163.128:2182,192.168.163.128:2183 # zookeeper 地址
  retryCount: 1 # 重試次數(shù)
  elapsedTimeMs: 2000 # 重試間隔時(shí)間
  sessionTimeoutMs: 60000 # session超時(shí)時(shí)間
  connectionTimeoutMs: 10000 # 連接超時(shí)時(shí)間

創(chuàng)建節(jié)點(diǎn)、刪除節(jié)點(diǎn)、獲取節(jié)點(diǎn)信息、分布式鎖的方法如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-650480.html

@Slf4j
@ActiveProfiles("company")
public class ZKClientTest extends BaseTest{

    @Resource
    private ZKClient zkClient;
    public static final int THREAD_NUM = 10;

    @Test
    public void distributedLock() throws InterruptedException, BrokenBarrierException {
        String lockPath = "/test/distributed2/lock";
        CuratorFramework client = zkClient.getClient();
        client.start();
        InterProcessMutex lock = new InterProcessMutex(client, lockPath);

        // 阻塞主線程,等待全部子線程執(zhí)行完
        CyclicBarrier cyclicBarrier = new CyclicBarrier(THREAD_NUM);

        for (int i = 0; i < THREAD_NUM; i++) {
            new Thread(() -> {
                log.info("{}->嘗試競(jìng)爭(zhēng)鎖", Thread.currentThread().getName());
                try {
                    lock.acquire(); // 阻塞競(jìng)爭(zhēng)鎖

                    log.info("{}->成功獲得鎖", Thread.currentThread().getName());
                    Thread.sleep(2000);

                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        lock.release(); //釋放鎖
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }, "Thread-" + i).start();
        }

        // 目的是為了等子線程搶完鎖再結(jié)束子線程,否則無法看到日志效果
        cyclicBarrier.await();
        log.info("全部子線程已執(zhí)行完畢");
    }

    @Test
    public void createNode() {
        // 創(chuàng)建一個(gè)ZNode節(jié)點(diǎn)
        String data = "hello";
        byte[] payload = data.getBytes(StandardCharsets.UTF_8);
        String zkPath = "/test/CRUD/node-1";

        zkClient.createNode(zkPath, payload);
        log.info("createNode succeeded!");

    }

    @Test
    public void getChildren() {
        String zkPath = "/test/CRUD";

        List<String> children = zkClient.getChildren(zkPath);
        printList(children);
    }

    @Test
    public void deleteNode() {
        String parentPath = "/test";

        log.info("======================Before delete===================");
        List<String> before = zkClient.getChildren(parentPath);
        printList(before);

        String zkPath = "/test/CRUD/node-1";
        zkClient.deleteNode(zkPath);
        log.info("delete node secceeded!");

        log.info("======================After delete===================");
        List<String> after = zkClient.getChildren(parentPath);
        printList(after);
    }

    private void printList(List<String> data) {
        if (!CollectionUtils.isEmpty(data)) {
            for (String datum : data) {
                log.info("datum:{}", data);
            }
        }
    }
}

到了這里,關(guān)于SpringBoot基于Zookeeper實(shí)現(xiàn)分布式鎖的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

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

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

    2024年04月24日
    瀏覽(28)
  • SpringBoot~ dubbo + zookeeper實(shí)現(xiàn)分布式開發(fā)的應(yīng)用

    SpringBoot~ dubbo + zookeeper實(shí)現(xiàn)分布式開發(fā)的應(yīng)用

    配置服務(wù)名字, 注冊(cè)中心地址, 掃描被注冊(cè)的包 server.port=8081 #當(dāng)前應(yīng)用名字 dubbo.application.name=provider-server #注冊(cè)中心地址 dubbo.registry.address=zookeeper://127.0.0.1:2181 #掃描指定包下服務(wù) dubbo.scan.base-packages=com.demo.service 實(shí)現(xiàn)一個(gè)接口,在接口中完成需求 public interface Translate { String tran

    2024年04月10日
    瀏覽(20)
  • 3、基于Zookeeper實(shí)現(xiàn)分布式鎖

    3、基于Zookeeper實(shí)現(xiàn)分布式鎖

    3.1.1 安裝啟動(dòng) 如下,說明啟動(dòng)成功: 3.1.2 相關(guān)概念 Zookeeper提供一個(gè)多層級(jí)的節(jié)點(diǎn)命名空間(節(jié)點(diǎn)稱為znode),每個(gè)節(jié)點(diǎn)都用一個(gè)以斜杠(/)分隔的路徑表示,而且每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn)(根節(jié)點(diǎn)除外),非常類似于文件系統(tǒng)。并且每個(gè)節(jié)點(diǎn)都是唯一的。 1、znode節(jié)點(diǎn)有四種類型

    2024年02月15日
    瀏覽(26)
  • 2.Zookeeper集成springboot操作節(jié)點(diǎn),事件監(jiān)聽,分布式鎖實(shí)現(xiàn)

    1.Springboot項(xiàng)目中添加zookeeper 已經(jīng)對(duì)應(yīng)的客戶端依賴 ,pom.xml文件如下 2.application.yml 文件中配置zookeeper連接的相關(guān)配置信息 3.java配置的方式添加zookeeper相關(guān)的配置 4.Zookeeper基礎(chǔ)操作服務(wù)和分布式鎖服務(wù)編碼 5.watcher機(jī)制事件處理抽象封裝 6.基本操作的單元測(cè)試代碼

    2024年03月10日
    瀏覽(22)
  • 第三章_基于zookeeper實(shí)現(xiàn)分布式鎖

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

    實(shí)現(xiàn)分布式鎖目前有三種流行方案,分別為基于數(shù)據(jù)庫、Redis、Zookeeper的方案。這里主要介紹基于zk怎么實(shí)現(xiàn)分布式鎖。在實(shí)現(xiàn)分布式鎖之前,先回顧zookeeper的知識(shí)點(diǎn)。 知識(shí)點(diǎn)回顧 Zookeeper(業(yè)界簡(jiǎn)稱zk)是一種提供配置管理、分布式協(xié)同以及命名的中心化服務(wù),這些提供的 功

    2024年02月09日
    瀏覽(21)
  • 基于 SpringBoot + Redis 實(shí)現(xiàn)分布式鎖

    基于 SpringBoot + Redis 實(shí)現(xiàn)分布式鎖

    大家好,我是余數(shù),這兩天溫習(xí)了下分布式鎖,然后就順便整理了這篇文章出來。 文末附有源碼鏈接,需要的朋友可以自取。 至于什么是分布式鎖,這里不做贅述,不了解的可以自行去查閱資料。 1. 使用 Redis 的 Setnx(SET if Not Exists) 命令加鎖。 即鎖不存在的時(shí)候才能加鎖成功

    2024年02月05日
    瀏覽(18)
  • 在Spring中,可以使用不同的方式來實(shí)現(xiàn)分布式鎖,例如基于數(shù)據(jù)庫、Redis、ZooKeeper等

    在Spring中,可以使用不同的方式來實(shí)現(xiàn)分布式鎖,例如基于數(shù)據(jù)庫、Redis、ZooKeeper等

    在Spring中,可以使用不同的方式來實(shí)現(xiàn)分布式鎖,例如基于數(shù)據(jù)庫、Redis、ZooKeeper等。下面是兩種常見的實(shí)現(xiàn)方式: 使用Redis實(shí)現(xiàn)分布式鎖: 使用自定義注解實(shí)現(xiàn)本地鎖: 以上是兩種常見的在Spring中實(shí)現(xiàn)分布式鎖的方式。第一種方式使用Redis作為分布式鎖的存儲(chǔ)介質(zhì),通過

    2024年03月17日
    瀏覽(24)
  • Zookeeper 和 Redis 哪種更好? 為什么使用分布式鎖? 1. 利用 Redis 提供的 第二種,基于 ZK 實(shí)現(xiàn)分布式鎖的落地方案 對(duì)于 redis 的分布式鎖而言,它有以下缺點(diǎn):

    關(guān)于這個(gè)問題,我們 可以從 3 個(gè)方面來說: 為什么使用分布式鎖? 使用分布式鎖的目的,是為了保證同一時(shí)間只有一個(gè) JVM 進(jìn)程可以對(duì)共享資源進(jìn)行操作。 根據(jù)鎖的用途可以細(xì)分為以下兩類: 允許多個(gè)客戶端操作共享資源,我們稱為共享鎖 這種鎖的一般是對(duì)共享資源具有

    2024年01月16日
    瀏覽(24)
  • 分布式鎖解決方案_Zookeeper實(shí)現(xiàn)分布式鎖

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

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

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

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

    2024年02月02日
    瀏覽(29)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包