zookeeper(2) 服务器动态上下线监听和分布式锁案例

案例一:服务器动态上下线监听

某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知 到主节点服务器的上下线。

1.服务端代码

package com.atguigu.case1;import org.apache.zookeeper.*;import java.io.IOException;
import java.nio.charset.StandardCharsets;public class DistributeServer {String connectString = "hadoop100:2181,hadoop101:2181,hadoop102:2181";int sessionTimeout = 20000;private ZooKeeper zooKeeper;public static void main(String[] args) throws IOException, InterruptedException, KeeperException {DistributeServer server = new DistributeServer();server.getConnect();server.regist(args[0]);server.business();}private void business() throws InterruptedException {Thread.sleep(Long.MAX_VALUE);}private void regist(String hostname) throws InterruptedException, KeeperException {String s = zooKeeper.create("/servers/", hostname.getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);System.out.println(hostname + "isonline");}private void getConnect() throws IOException {zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {}});}
}

2.客户端代码

package com.atguigu.case1;import org.apache.zookeeper.*;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;public class DistributeClient {String connectString = "hadoop100:2181,hadoop101:2181,hadoop102:2181";int sessionTimeout = 20000000;private ZooKeeper zooKeeper;public static void main(String[] args) throws IOException, InterruptedException, KeeperException {DistributeClient client = new DistributeClient();client.getConnect();client.getServerList();client.business();}private void getServerList() throws InterruptedException, KeeperException {List<String> children = zooKeeper.getChildren("/servers", true);ArrayList<String> servers = new ArrayList<>();for (int i = 0; i < children.size(); i++) {byte[] data = zooKeeper.getData("/servers/" + children.get(i), false, null);servers.add(new String(data));}System.out.println(servers);}private void business() throws InterruptedException {Thread.sleep(Long.MAX_VALUE);}private void regist(String hostname) throws InterruptedException, KeeperException {String s = zooKeeper.create("/servers/"+hostname, hostname.getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);System.out.println(hostname + "isonline");}private void getConnect() throws IOException {zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {try {getServerList();} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}});}
}

案例二:分布式锁案例原生方法

package com.atguigu.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 {String connectString = "hadoop100:2181,hadoop101:2181,hadoop102:2181";int sessionTimeout = 2000;private final ZooKeeper zooKeeper;private CountDownLatch connectLatch  = new CountDownLatch(1);private CountDownLatch waitLatch  = new CountDownLatch(1);private String waitPath;private String currentMode;public DistributedLock() throws IOException, InterruptedException, KeeperException {//获取连接zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {//监听到前一个节点已经下线//connectLatch 如果连上需要释放if(watchedEvent.getState() == Event.KeeperState.SyncConnected) {connectLatch.countDown();}//waitLatch 需要释放if(watchedEvent.getType() == Event.EventType.NodeDeleted&&watchedEvent.getPath().equals(waitPath)){waitLatch.countDown();}}});//等待zk正常连接后,才往下走connectLatch.await();//判断根节点/locks是否存在Stat stat = zooKeeper.exists("/locks", false);if(stat == null) {//创建根节点zooKeeper.create("/locks","locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);}}//加锁public void zklock(){//创建对应的临时的带序号的节点try {currentMode = zooKeeper.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);//判断创建的节点是否是最小的节点,如果是获取到锁;不是,监听前一个序号最小的节点List<String> children = zooKeeper.getChildren("/locks", false);//如果children只有一个值,那就直接获取锁;如果有多个节点,需要判断谁最小if(children.size() == 1) {return;} else {//排序Collections.sort(children);//获取当前节点名称String thisNode = currentMode.substring("/locks/".length());//通过thisNode获取在children集合中的位置int index = children.indexOf(thisNode);if(index == -1) {System.out.println("数据异常");}else if(index == 0) {//就一个节点数据,就可以获取锁了return;}else {//需要监听 前一个节点变化waitPath = "/locks/"+children.get(index-1);zooKeeper.getData(waitPath,true,null);//等待监听waitLatch.await();//接收到之后return;}}} catch (KeeperException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}public void unZklock(){//删除节点try {zooKeeper.delete(currentMode,-1);} catch (InterruptedException e) {e.printStackTrace();} catch (KeeperException e) {e.printStackTrace();}}
}

测试

package com.atguigu.case2;import org.apache.zookeeper.KeeperException;import java.io.IOException;public class DistributedLockTest {public static void main(String[] args) throws IOException, InterruptedException, KeeperException {DistributedLock lock1 = new DistributedLock();DistributedLock lock2 = new DistributedLock();new Thread(new Runnable(){@Overridepublic 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(){@Overridepublic void run() {try {lock2.zklock();System.out.println("线程2启动获取到锁");Thread.sleep(5000);lock2.unZklock();System.out.println("线程2释放锁");} catch (InterruptedException e) {e.printStackTrace();}}}).start();}
}

 案例三:分布式锁案例框架方法

引入包

        <dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.3.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.3.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-client</artifactId><version>4.3.0</version></dependency>
package com.atguigu.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;public class CuratorLockTest {public static void main(String[] args) {//创建分布式锁1InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");//创建分布式锁2InterProcessMutex lock2 = new InterProcessMutex(getCuratorFramework(), "/locks");new Thread(new Runnable(){@Overridepublic void run() {try {lock1.acquire();System.out.println("线程1获取到锁");lock1.acquire();System.out.println("线程1再次获取到锁");lock1.release();System.out.println("线程1释放锁");lock1.release();System.out.println("线程1再次释放锁");} catch (Exception e) {e.printStackTrace();}}}).start();new Thread(new Runnable(){@Overridepublic void run() {try {lock2.acquire();System.out.println("线程2获取到锁");lock2.acquire();System.out.println("线程2再次获取到锁");lock2.release();System.out.println("线程2释放锁");lock2.release();System.out.println("线程2再次释放锁");} catch (Exception e) {e.printStackTrace();}}}).start();}private static CuratorFramework getCuratorFramework() {ExponentialBackoffRetry policy = new ExponentialBackoffRetry(3000, 3);CuratorFramework client = CuratorFrameworkFactory.builder().connectString("hadoop100:2181,hadoop101:2181,hadoop102:2181").connectionTimeoutMs(2000).sessionTimeoutMs(2000).retryPolicy(policy).build();client.start();System.out.println("zookeeper启动成功");return client;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/249424.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态时序分析:时序弧以及其时序敏感(单调性)

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在静态时序分析中&#xff0c;不管是组合逻辑单元&#xff08;如与门、或门、与非门等&#xff09;还是时序逻辑&#xff08;D触发器等&#xff09;在时序建模时…

springCloud gateway 防止XSS漏洞

springCloud gateway 防止XSS漏洞 一.XSS(跨站脚本)漏洞详解1.XSS的原理和分类2.XSS漏洞的危害3.XSS的防御 二.Java开发中防范XSS跨站脚本攻击的思路三.相关代码&#xff08;适用于spring cloud gateway&#xff09;1.CacheBodyGlobalFilter.java2.XssRequestGlobalFilter.java…

强大的虚拟机Parallels Desktop 19 mac中文激活

Parallels Desktop是一款功能全面、易于使用的虚拟机软件&#xff0c;它为用户提供了在Mac电脑上同时运行多个操作系统的便利。 软件下载&#xff1a;Parallels Desktop 19 mac中文激活版下载 Parallels Desktop 19 mac具有快速启动和关闭虚拟机的能力&#xff0c;让用户能够迅…

STM32G4 系列命名规则

STM32G4产品线 基础型系列STM32G4x1 具有入门级模拟外设配置&#xff0c;单存储区Flash&#xff0c;支持的Flash存储器容量范围从32到512KB。 增强型系列STM32G4x3 与基本型器件相比具有更多数量的模拟外设&#xff0c;以及双存储区Flash&#xff0c;Flash存储器容量也提高…

C#学习笔记_类(Class)

类的定义 类的定义是以关键字 class 开始&#xff0c;后跟类的名称。类的主体&#xff0c;包含在一对花括号内。 语法格式如下&#xff1a; 访问标识符 class 类名 {//变量定义访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;访问标识符 数据类型 变量名;......//方…

【Day37】代码随想录之贪心_738.单调递增的数字_968.监控二叉树

文章目录 738.单调递增的数字968.监控二叉树 738.单调递增的数字 参考文档&#xff1a;代码随想录 题目&#xff1a; 给定一个非负整数 N&#xff0c;找出小于或等于 N 的最大的整数&#xff0c;同时这个整数需要满足其各个位数上的数字是单调递增。 &#xff08;当且仅当每个相…

你的MiniFilter安全吗?

简介 筛选器管理器 (FltMgr.sys)是Windows系统提供的内核模式驱动程序, 用于实现和公开文件系统筛选器驱动程序中通常所需的功能; 第三方文件系统筛选器开发人员可以使用FltMgr的功能可以更加简单的编写文件过滤驱动, 这种驱动我们通常称为MiniFilter, 下面是MiniFilter的基本…

基于SpringBoot+Vue学科竞赛管理系统

文章目录 基于SpringBootVue学科竞赛管理系统1系统概述1.3系统设计思想 2相关技术2.1 MYSQL数据库2.2 B/S结构2.3 Spring Boot框架简介2.4 Vue简介 3系统分析3.1可行性分析3.1.1技术可行性3.1.2经济可行性3.1.3操作可行性 3.2系统性能分析3.2.1 系统安全性3.2.2 数据完整性 3.4…

【2024】大三寒假再回首:缺乏自我意识是毒药,反思和回顾是解药

2024年初&#xff0c;学习状态回顾 开稿时间&#xff1a;2024-1-23 归家百里去&#xff0c;飘雪送客迟。 搁笔日又久&#xff0c;一顾迷惘时。 我们饱含着过去的习惯&#xff0c;缺乏自我意识是毒药&#xff0c;反思和回顾是解药。 文章目录 2024年初&#xff0c;学习状态回顾一…

虚拟机(VMware)ubuntu16.04 直接连接网口设备 USRP 吊舱

编辑虚拟网络编辑器 点击之后 选择网卡之后&#xff0c;点击确定。 电脑配置 使用了&#xff1a;192.168.2.56 虚拟机内部配置 和PC的配置一致

【Matlab】音频信号分析及FIR滤波处理——凯泽(Kaiser)窗

一、前言 1.1 课题内容: 利用麦克风采集语音信号(人的声音、或乐器声乐),人为加上环境噪声(窄带)分析上述声音信号的频谱,比较两种情况下的差异根据信号的频谱分布,选取合适的滤波器指标(频率指标、衰减指标),设计对应的 FIR 滤波器实现数字滤波,将滤波前、后的声音…

Zoho Mail 2023:回顾过去,展望未来:不断进化的企业级邮箱解决方案

当我们告别又一个非凡的一年时&#xff0c;我们想回顾一下Zoho Mail如何融合传统与创新。我们迎来了成立15周年&#xff0c;这是一个由客户、合作伙伴和我们的敬业团队共同庆祝的里程碑。与我们一起回顾这段旅程&#xff0c;探索定义Zoho Mail历史篇章的敏捷性、精确性和创新性…

Spring 事务原理二

该说些什么呢&#xff1f;一连几天&#xff0c;我都沉溺在孤芳自赏的思维中无法自拔。不知道自己为什么会有这种令人不齿的表现&#xff0c;更不知道这颗定时炸弹何时会将人炸的粉身碎骨。好在儒派宗师曾老夫子“吾日三省吾身”的名言警醒了我。遂潜心自省&#xff0c;溯源头以…

C++初阶入门之命名空间和缺省参数的详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.命名空间 2.1命名冲突的例子 2.2解决方案 2.3命…

MyBatis概述与MyBatis入门程序

MyBatis概述与MyBatis入门程序 一、MyBatis概述二、入门程序1.准备开发环境&#xff08;1&#xff09;准备数据库&#xff08;2&#xff09;创建一个maven项目 2.编写代码&#xff08;1&#xff09;打包方式和引入依赖&#xff08;2&#xff09;新建mybatis-config.xml配置⽂件…

node.js(nest.js控制器)学习笔记

nest.js控制器&#xff1a; 控制器负责处理传入请求并向客户端返回响应。 为了创建基本控制器&#xff0c;我们使用类和装饰器。装饰器将类与所需的元数据相关联&#xff0c;并使 Nest 能够创建路由映射&#xff08;将请求绑定到相应的控制器&#xff09;。 1.获取get请求传参…

祖传代码里的神逻辑

昨天做权限限制的需求&#xff0c;给自己配置了两个新的分组&#xff0c;然后就发现登录不了项目了&#xff0c;sql报错ORA-01795: maximum number of expressions in a list is 1000&#xff0c;一路debugger找到了元凶&#xff0c;看逻辑是想把两个不同表里的分组去重然后合并…

【CMU-自主导航与规划】M-TARE planner 配置与运行

M-TARE docker M-TARE 源码 一、依赖 Docker, Docker Compose, NVIDIA Container Toolkit, Nvidia GPU Driver&#xff08;需要至少2个&#xff0c;带Nvidia GPU&#xff09; 1.1 Docker docker -v #查询版本1.2 Docker Compose docker compose version1.3 …

分布式搜索引擎_学习笔记_3

分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合&#xff08;aggregations&#xff09;**可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f;这些手机的平均价格、最高价格、最低价格&#xff1f;这些手机每月的销售…

Here Document免交互和Expect

文章目录 Here Document免交互和Expect自动化交互一、Here Document—免交互1、Here Document 免交互概述2、语法格式3、免交互的用法3.1 cat命令3.2 tee命令3.3 wc命令3.4 read命令3.5 passwd命令 4、Here Document 变量设定 二、Expect自动化交互1、expect基本使用1.1 脚本解…