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() {
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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(){
            @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();
    }
}

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

引入包

        <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) {
        //创建分布式锁1
        InterProcessMutex lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");
        //创建分布式锁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再次获取到锁");

                    lock1.release();
                    System.out.println("线程1释放锁");

                    lock1.release();
                    System.out.println("线程1再次释放锁");

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable(){
            @Override
            public 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;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | 损失函数篇 | 更加聚焦的边界框损失Focaler-IoU、InnerFocalerIoU(二次创新)

一、本文介绍 本文给大家带来的改进机制是更加聚焦的边界框损失Focaler-IoU已经我进行二次创新的InnerFocalerIoU同时本文的内容支持现阶段的百分之九十以上的IoU,比如Focaler-IoU、Focaler-ShapeIoU、Inner-Focaler-ShapeIoU包含非常全的损失函数,边界框的损失函数只看这一…

【每日一题】6.LeetCode——轮转数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》|《数据结构与算法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有限&#xff0c;欢…

Spring Boot第一天

SpringBoot概述 Spring Boot是Spring提供的一个子项目&#xff0c;用于快速构建Spring应用程序 传统方式构建Spring应用程序 导入依赖繁琐 项目配置繁琐 为了简化如此繁琐的配置流程&#xff0c;SpringBoot这一子项目提供了如下特性 SpringBoot特性 起步依赖 本质上就是一个…

集显如何安装pytorch (CPU)

目录 前言1. 注意事项2. CPU版 前言 此为记录贴&#xff0c;原先都是独显&#xff0c;安装GPU&#xff0c;第一次查看发现是集显&#xff0c;没有配备的GPU 1. 注意事项 验证自身是否为独显&#xff1a;cmd下执行 DxDiag 如果Graphics则为集显&#xff0c;代表只能操作CPU模…

腾讯云幻兽帕鲁Palworld服务器价格表,2024年2月最新

腾讯云幻兽帕鲁服务器价格32元起&#xff0c;4核16G12M配置32元1个月、96元3个月、156元6个月、312元一年&#xff0c;支持4-8个玩家&#xff1b;8核32G22M幻兽帕鲁服务器115元1个月、345元3个月&#xff0c;支持10到20人在线开黑。腾讯云百科txybk.com分享更多4核8G12M、16核6…

DevOps落地笔记-03|用户故事:对用户需求达成共识的关键

上一讲主要跟你介绍了如何使用影响地图这个工具来进行产品定义、里程碑规划和用户需求分析。影响地图让我们始终以达到目标为核心&#xff0c;并让功能和需求不偏离该目标&#xff0c;从而让交付更有重点。可视化、结构化的思维导图为技术和业务人员创建了共享的整体视图&#…

【AI视野·今日Robot 机器人论文速览 第七十七期】Mon, 15 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Mon, 15 Jan 2024 Totally 14 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Learning Joint Space Reference Manifold for Reliable Physical Assistance Authors Amirreza Razmjoo, Tilen Brecelj, Kri…

VUE3+elementPlus 之 Form表单校验器 之 字符长度校验

需求&#xff1a;校验字符长度&#xff0c;超过后仍可输入&#xff0c;error提示录入字符数与限制字符数 校验字符长度&#xff1a; /*** 检验文字输入区的长度* param {*} rule 输入框的rule 对象&#xff0c;field&#xff1a;字段名称* param {*} value …

【京东云新品发布月刊】2024年1月产品动态来啦

1&#xff09;【莫奈可视化平台】新品上线 京东莫奈可视化平台通过自由拖拽、图形化编辑、所见即所得的方式&#xff0c;快速实现极致酷炫、直观清晰的视觉场景&#xff0c;将海量繁杂数据背后所蕴含的价值更直观、深层、全面的展现出来&#xff0c;辅助决策者合理决策。 2&a…

【Oracle云】OCI DevOps Services 构建自动化流水线 (1) - 基础架构流程 OCI 代码仓库使用

OCI DevOps Services 是 Oracle Cloud Infrastructure (OCI) 提供的一项独立的 CI/CD 服务&#xff0c;旨在支持用户构建自动化的流水线&#xff0c;实现更高效、可靠的软件交付。在本系列的第一篇文章中&#xff0c;我们将深入探讨 OCI DevOps Services 的基础架构流程&#x…

基于MATLAB实现的OFDM仿真调制解调,BPSK、QPSK、4QAM、16QAM、32QAM,加性高斯白噪声信道、TDL瑞利衰落信道

基于MATLAB实现的OFDM仿真调制解调&#xff0c;BPSK、QPSK、4QAM、16QAM、32QAM&#xff0c;加性高斯白噪声信道、TDL瑞利衰落信道 相关链接 OFDM中的帧&#xff08;frame&#xff09;、符号&#xff08;symbol&#xff09;、子载波&#xff08;subcarriers&#xff09;、导频…

JVM工作原理与实战(三十一):诊断内存泄漏的原因

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、诊断原因 二、MAT内存泄漏检测的原理 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码&#xff0c;管理内存&#xff0c;确保安全&#xff0c;支持多线…

网络异常案例五_SYN被丢弃

问题现象 公司同事使用的时候&#xff0c;反馈系统不稳定&#xff0c;访问的时候&#xff0c;有时候会出现白屏&#xff08;连接超时&#xff09;&#xff0c;或者系统页面点击没有响应&#xff0c;过一会之后刷新系统又可以正常展示了。之前未收到过类似反馈&#xff0c;一直…

༺༽༾ཊ—Unity之-02-抽象工厂模式—ཏ༿༼༻

首先创建一个项目&#xff0c; 在这个初始界面我们需要做一些准备工作&#xff0c; 建基础通用文件夹&#xff0c; 创建一个Plane 重置后 缩放100倍 加一个颜色&#xff0c; 任务&#xff1a;使用 抽象工厂模式 创建 人物与宠物 模型&#xff0c; 首先资源商店下载 人物与宠物…

huggingface打不开,解决方法

解决方法 将 https://huggingface.co/hustvl/Vim-tiny替换成 https://hf-mirror.com/hustvl/Vim-tiny文章目录 解决方法摘要YoloV8改进策略&#xff1a;基于分层注意力的FasterViT&#xff0c;让YoloV8实现性能的飞跃YoloV8改进策略&#xff1a;InceptionNext主干替换YoloV8…

第九节HarmonyOS 常用基础组件21-ImageAnimator

1、描述 提供帧动画组件来实现逐帧播放图片的能力&#xff0c;可以配置需要播放的图片列表&#xff0c;每张图片可以配置时长。 2、接口 ImageAnimator() 3、属性 参数名 参数类型 描述 images Array<ImageFrameInfo> 设置图片帧信息集合&#xff0c;每一帧的帧…

【零基础学习CAPL】——CAN报文的发送(按下按钮同时周期性发送)

🙋‍♂️【零基础学习CAPL】系列💁‍♂️点击跳转 文章目录 1.概述2.面板创建3.系统变量创建4.CAPL实现4.1.函数展示4.2.全量报文展示5.效果1.概述 本章主要介绍使用CAPL和Panel在按下按钮时发送周期性CAN报文。 本章主要在“【零基础学习CAPL】——CAN报文的发送(配合P…

二叉树-堆应用(1)

目录 堆排序 整体思路 代码实现 Q1建大堆/小堆 Q2数据个数和下标 TopK问题 整体思路 代码实现 Q1造数据CreateData Q2建大堆/小堆 建堆的两种方法这里会用到前面的向上/向下调整/交换函数。向上调整&向下调整算法-CSDN博客 堆排序 整体思路 建堆&#xff08;直…

android远程投屏应用

客户端app地址&#xff1a;https://gitee.com/youzilzk/blue1.git 服务端地址&#xff1a;https://gitee.com/youzilzk/blue-server1.git 一。服务端部署 1.安装postgres 2.导入项目下blue.sql文件 3.修改配置application.properties和config.properties&#xff0c;其中applic…

Flask框架开发学习笔记《6》前后端不分离基础框架

Flask框架开发学习笔记《6》前后端不分离基础框架 Flask是使用python的后端&#xff0c;由于小程序需要后端开发&#xff0c;遂学习一下后端开发。 主要包含如下文件&#xff1a; static 目录中存储了图片templates 目录中存储了 html 文件utils.py 包含了 log 函数server.p…