Zookeeper(58)如何在Zookeeper中实现分布式锁?
在 Zookeeper 中实现分布式锁是一种常见的用例。Zookeeper 提供了强一致性、高可用性的分布式协调服务,使得它非常适合用来实现分布式锁。以下是详细的步骤和代码示例,展示如何在 Zookeeper 中实现分布式锁。
1. Zookeeper 分布式锁的基本原理
Zookeeper 分布式锁的实现主要依赖于以下几点:
- 临时顺序节点:每个客户端在尝试获取锁时,会在特定节点下创建一个临时顺序节点。
- 节点排序:所有客户端创建的节点会按顺序排列,最小的节点获得锁。
- 监视前一个节点:每个客户端监视它前一个节点的变化,当前一个节点被删除时,当前客户端重新检查自己是否是最小的节点,如果是,则获得锁。
2. 添加依赖
首先,需要在项目中添加 Zookeeper 的依赖。以下是 Maven 和 Gradle 的依赖配置:
Maven
在 pom.xml
中添加 Zookeeper 依赖:
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.7.0</version>
</dependency>
Gradle
在 build.gradle
中添加 Zookeeper 依赖:
dependencies {implementation 'org.apache.zookeeper:zookeeper:3.7.0'
}
3. 实现分布式锁
以下是一个完整的实现分布式锁的示例代码。
ZookeeperClient.java
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;public class ZookeeperClient {private static final String ZK_ADDRESS = "localhost:2181";private static final int SESSION_TIMEOUT = 3000;private ZooKeeper zooKeeper;public void connect() throws Exception {zooKeeper = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, new Watcher() {@Overridepublic void process(WatchedEvent event) {System.out.println("Received event: " + event);}});}public void close() throws InterruptedException {if (zooKeeper != null) {zooKeeper.close();}}public ZooKeeper getZooKeeper() {return zooKeeper;}public static void main(String[] args) {ZookeeperClient client = new ZookeeperClient();try {client.connect();// 在这里可以测试分布式锁client.close();} catch (Exception e) {e.printStackTrace();}}
}
DistributedLock.java
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;import java.util.Collections;
import java.util.List;public class DistributedLock {private static final String LOCK_ROOT = "/locks";private static final String LOCK_NODE = LOCK_ROOT + "/lock_";private ZooKeeper zooKeeper;private String lockPath;public DistributedLock(ZooKeeper zooKeeper) throws Exception {this.zooKeeper = zooKeeper;Stat stat = zooKeeper.exists(LOCK_ROOT, false);if (stat == null) {zooKeeper.create(LOCK_ROOT, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}}public void acquireLock() throws Exception {lockPath = zooKeeper.create(LOCK_NODE, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);System.out.println("Lock path: " + lockPath);while (true) {List<String> children = zooKeeper.getChildren(LOCK_ROOT, false);Collections.sort(children);String smallestChild = LOCK_ROOT + "/" + children.get(0);if (lockPath.equals(smallestChild)) {System.out.println("Acquired lock: " + lockPath);return;}String watchNode = null;for (int i = children.size() - 1; i >= 0; i--) {String child = LOCK_ROOT + "/" + children.get(i);if (child.compareTo(lockPath) < 0) {watchNode = child;break;}}if (watchNode != null) {final Object lock = new Object();Watcher watcher = new Watcher() {@Overridepublic void process(WatchedEvent event) {synchronized (lock) {lock.notifyAll();}}};Stat stat = zooKeeper.exists(watchNode, watcher);if (stat != null) {synchronized (lock) {lock.wait();}}}}}public void releaseLock() throws Exception {if (lockPath != null) {zooKeeper.delete(lockPath, -1);System.out.println("Released lock: " + lockPath);lockPath = null;}}public static void main(String[] args) {ZookeeperClient client = new ZookeeperClient();try {client.connect();ZooKeeper zooKeeper = client.getZooKeeper();DistributedLock lock = new DistributedLock(zooKeeper);lock.acquireLock();// 模拟业务逻辑Thread.sleep(5000);lock.releaseLock();client.close();} catch (Exception e) {e.printStackTrace();}}
}
4. 代码说明
ZookeeperClient 类
ZookeeperClient
类负责连接和关闭 Zookeeper 客户端,并提供获取 ZooKeeper
实例的方法。
DistributedLock 类
DistributedLock
类负责实现分布式锁的逻辑,包括获取锁和释放锁。
- acquireLock() 方法:尝试获取锁,创建临时顺序节点,然后检查自己是否是最小的节点。如果是,则获得锁;否则,监视前一个节点的变化。
- releaseLock() 方法:释放锁,删除自己创建的临时顺序节点。
5. 测试分布式锁
在 DistributedLock
类的 main
方法中,创建 ZookeeperClient
实例并连接 Zookeeper,然后创建 DistributedLock
实例并尝试获取和释放锁。可以通过运行多个实例来测试分布式锁的功能。
public static void main(String[] args) {ZookeeperClient client = new ZookeeperClient();try {client.connect();ZooKeeper zooKeeper = client.getZooKeeper();DistributedLock lock = new DistributedLock(zooKeeper);lock.acquireLock();// 模拟业务逻辑Thread.sleep(5000);lock.releaseLock();client.close();} catch (Exception e) {e.printStackTrace();}
}
总结
- 添加依赖:在项目中添加 Zookeeper 的依赖。
- 实现 ZookeeperClient 类:负责连接和关闭 Zookeeper 客户端,并提供获取
ZooKeeper
实例的方法。 - 实现 DistributedLock 类:负责实现分布式锁的逻辑,包括获取锁和释放锁。
- 测试分布式锁:通过运行多个实例来测试分布式锁的功能。
通过以上方法,可以在 Zookeeper 中实现分布式锁,确保其高效稳定地运行。根据实际情况和需求,选择适合你的实现方法并进行实施。
相关文章:
Zookeeper(58)如何在Zookeeper中实现分布式锁?
在 Zookeeper 中实现分布式锁是一种常见的用例。Zookeeper 提供了强一致性、高可用性的分布式协调服务,使得它非常适合用来实现分布式锁。以下是详细的步骤和代码示例,展示如何在 Zookeeper 中实现分布式锁。 1. Zookeeper 分布式锁的基本原理 Zookeep…...

Mac端homebrew安装配置
拷打了一下午o3-mini-high,不如这位博主的超强帖子,10分钟结束战斗 跟随该文章即可,2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次,点赞258次,收藏837次。一直觉得自己写…...
Spring 接入 DeepSeek
引入依赖 <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId> </dependency>2.yml配置 spring:ai:openai:api-key: sk-xxxxx // 填写自己申请的keybase-url: http…...
vscode将文件中行尾默认CRLF改为LF
安装prettier npm install --save-dev --save-exact prettier执行命令 npx prettier --write --end-of-line lf .即可将项目中的所有文件行尾序列格式改为lf *在你使用git拉取代码的时候,git会自动将代码当中与你当前系统不同的换行方式转化成你当前系统的换行方…...

python-leetcode 33.排序链表
题目: 给定链表的头结点head,请将其按升序排列,并返回排序后的链表 方法一:自顶向下归并排序 链表自顶向下归并排序的过程: 1.找到链表的中点,以中点为分界,将链表拆分成两个子链表。寻找链表的中点可以…...

【数据结构初阶第十二节】设计循环队列
云边有个稻草人-CSDN博客 必须有为成功付出代价的决心,然后想办法付出这个代价。 还有最后一道关于队列的习题,这题有点难,准备好迎接挑战吧! 目录 1.【题目】 2.实现循环队列推荐用数组,Why? 3.Q1:如…...

基于微信小程序的民宿短租系统设计与实现(ssm论文源码调试讲解)
第4章 系统设计 4.1系统设计的目标 系统设计的目标是满足用户的需求和满足系统实现所需要的所有要求。本系统收集了信息浏览、信息删除、信息添加、信息修改、信息查询为一体[17]。改变了用户民宿短租的方式,提高管理员管理效率以及用户预订的效率。为用户、房主提…...
使用 Jetty 构建 HTTPS 服务入门指南
在互联网安全越来越重要的今天,使用 HTTPS 为 Web 服务提供安全传输成为标准配置。Jetty 是一个高性能、易用且功能丰富的开源 Java HTTP 服务器和 Servlet 容器,能够轻松实现 HTTPS 支持。本文将结合代码实例,引导您快速搭建一个基于 Jetty 的 HTTPS 服务。 一、Jetty 简介…...
数据结构《图》
数据结构《图论》 图的性质 一、无向图(Undirected Graph) 定义 由一组顶点(Vertex)和一组无向边(Edge)构成。 每条无向边用一条无方向的线段连接两个顶点,记为 ( (u, v) ),其中…...

用Chrome Recorder轻松完成自动化测试脚本录制
前言 入门自动化测试,录制回放通常是小白测试首先用到的功能。而录制回放工具也一直是各大Web自动化测试必然会着重提供的一块功能。 早期WinRunner、QTP这样的工具,自动化测试可以说是围绕录制回放开展的。近年像Selenium也提供有录制工具 Selenium IDE,Playwright也包含…...

⭐️苹果电脑安装windows10双系统【详细图文步骤保姆级教程】【本教材适用于MAC台式机、笔记本MacBook air和pro】
苹果电脑安装windows10双系统【详细图文步骤保姆级教程】【本教材适用于MAC台式机、笔记本MacBook air和pro】 苹果电脑安装windows10双系统一、准备工作准备项1:U盘作为系统安装盘准备项2:您需要安装的系统镜像 二、启动转换助理步骤1:找到启…...

win10系统上的虚拟机安装麒麟V10系统提示找不到操作系统
目录预览 一、问题描述二、原因分析三、解决方案四、参考链接 一、问题描述 win10系统上的虚拟机安装麒麟V10系统提示找不到操作系统,报错:Operating System not found 二、原因分析 国产系统,需要注意的点: 需要看你的系统类…...

Java 大视界 -- 开源社区对 Java 大数据发展的推动与贡献(91)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...

深入浅出C语言内存模型——高阶篇
在C语言编程的征途上,内存管理无疑是最具挑战性的部分之一。今天,我们将深入探讨C语言的内存模型,剖析其高级特性,并通过一系列案例,助你成为内存管理的佼佼者。本文为高阶篇,适合已经有一定C语言基础的读者…...
AI 百炼成神:逻辑回归, 垃圾邮件分类
第二个项目:逻辑回归垃圾邮件分类 项目代码下载地址:https://download.csdn.net/download/m0_56366541/90398247 项目目标 学习逻辑回归的基本概念。使用逻辑回归算法来实现垃圾邮件的分类。理解如何处理文本数据以及如何评估分类模型的性能。项目步骤 准备数据集 我们将使…...

MybatisPlus-扩展功能
逻辑删除乐观锁 MyBatisPlus从入门到精通-3(含mp代码生成器) Db静态工具类 Spring依赖循环问题 代码生成器 MybatisPlus代码生成器 枚举处理器 我们这里用int来存储状态 需要注解,很不灵活 希望用枚举类来代替这个Integer 这样的话我…...

《计算机视觉》——角点检测和特征提取sift
角点检测 角点的定义: 从直观上理解,角点是图像中两条或多条边缘的交点,在图像中表现为局部区域内的灰度变化较为剧烈的点。在数学和计算机视觉中,角点可以被定义为在两个或多个方向上具有显著变化的点。比如在一幅建筑物的图像…...

DeepSeek模型快速部署教程-搭建自己的DeepSeek
前言:在人工智能技术飞速发展的今天,深度学习模型已成为推动各行各业智能化转型的核心驱动力。DeepSeek 作为一款领先的 AI 模型,凭借其高效的性能和灵活的部署方式,受到了广泛关注。无论是自然语言处理、图像识别,还是…...
Swift CChar元祖转String
iOS有些API是调用C函数,Swift端获得的数据是CChar元祖,需要转成String方便使用,下面的代码以获取手机型号为例 方式一 var systemInfo utsname() uname(&systemInfo) let deviceModel withUnsafePointer(to: systemInfo.machine) { …...
【刷题】leetcode
题目 现有 s e r v e r N u m 台服务器,编号依次为 1 − s e r v e r...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...