zk111111111111111111
Curator 一套操作 zookeeper 的 Java api:
pom.xml 文件(注意在版本上有限制,直接使用交高的版本)
<!--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>
(1) 创建连接 zookeeper 的对象(可以抽取为工具类):
代码:
package utils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* @ClassName: CuratorUtils
* @Author: nanfeng
* @Date: 2021/1/20 11:26
* @Description: curator 发音: [ˈkjʊrˌeɪdər]
*/
public class CuratorUtils {
private static CuratorFramework client;
static {
/*
* @param connectString 连接字符串。zk server 地址和端口
"192.168.149.135:2181,
* 192.168.149.136:2181" 多个连接地址
* @param sessionTimeoutMs 会话超时时间 单位 ms
* @param connectionTimeoutMs 连接超时时间 单位 ms
* @param retryPolicy 重试策略
*/
// 重试策略:参数为休眠时间和最大重试次数
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
/*
//1.第一种方式
CuratorFramework client =
CuratorFrameworkFactory.newClient("192.168.149.135:2181",
60 * 1000, 15 * 1000, retryPolicy);
*/
//2.第二种方式:链式创建
//CuratorFrameworkFactory.builder();
client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2181") //zookeeper 的连接地
址和端口号
.sessionTimeoutMs(60 * 1000) //会话时间
.connectionTimeoutMs(15 * 1000) //连接超时时间
.retryPolicy(retryPolicy) //重试策略
.namespace("nanfeng") //名称空间,可有可无,
根据情况进行添加
.build();
//开启连接
client.start();
}
/**
* 获取连接对象
*
* @param client
* @return
*/
public static CuratorFramework getClient(CuratorFramework client) {
return client;
}
/**
* 释放连接
*
* @param client
*/
public static void clossConnection(CuratorFramework client) {
if (client != null) {
client.close(); }}}
(2) 进行基本的增删改查:
package test;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;
import utils.CuratorUtils;
import java.util.Arrays;
import java.util.List;
/**
* @ClassName: curatorTest
* @Author: nanfeng
* @Date: 2021/1/20 14:40
* @Description: Curator 的 api 操作 zookeeper
*/
public class CuratorTest {
private static CuratorFramework client;
/*获取公共的连接对象*/
static {
client = CuratorUtils.getClient();
}
/* 创建节点
*/
/**
* 创建节点:create 持久 临时 顺序 数据
* 1. 基本创建 :create().forPath("")
* 2. 创建节点 带有数据:create().forPath("",data)
* 3. 设置节点的类型:create().withMode().forPath("",data)
* 4. 创建多级节点 /app1/p1 :
create().creatingParentsIfNeeded().forPath("",data)
*/
@Test
/*增加*/
public void addZnode1() throws Exception {
//创建节点
String nanfeng1 = client.create().forPath("/nanfeng1");
System.out.println(nanfeng1);
//释放连接
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode2() throws Exception {
//创建节点带有数据
String nanfeng2 = client.create().forPath("/nanfeng2",
"nanfeng2".getBytes());
System.out.println(nanfeng2);
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode3() throws Exception {
//创建节点设置节点类型
//节点默认类型为持久化的
String nanfeng3w =
client.create().withMode(CreateMode.EPHEMERAL).forPath("/nanfeng3");
System.out.println(nanfeng3w);
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode4() throws Exception {
//创建多级节点
String s =
client.create().creatingParentContainersIfNeeded().forPath("/nanfeng4
/nanzi");
System.out.println(s);
CuratorUtils.clossConnection(client);
}
/* 删除节点 */
/**
* 删除节点: delete deleteall
* 1. 删除单个节点:delete().forPath("/app1");
* 2. 删除带有子节点的节
点:delete().deletingChildrenIfNeeded().forPath("/app1");
* 3. 必须成功的删除:为了防止网络抖动。本质就是重试。
client.delete().guaranteed().forPath("/app2");
* 4. 回调:inBackground
*
* @throws Exception
*/
/* 关于回调函数: 在执行某项操作时,自动开启自定义的一系列业务,即
监听执行 */
@Test
/*删除*/
public void deleteZnode1() throws Exception {
//删除单个节点
client.delete().forPath("/nanfeng1");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode2() throws Exception {
//删除带有子节点的节点
client.delete().deletingChildrenIfNeeded().forPath("/nanfeng4");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode3() throws Exception {
//强制删除(必须删除成功)
client.delete().guaranteed().forPath("/nanfeng2");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode4() throws Exception {
//删除回调(可以完成一些特殊的功能)
client.delete().guaranteed().inBackground(new
BackgroundCallback() {
@Override
public void processResult(CuratorFramework
curatorFramework, CuratorEvent curatorEvent) throws Exception {
//回调
//此处执行特定功能,
System.out.println("回调函数触发了");
}
}).forPath("/nanfeng3");
CuratorUtils.clossConnection(client);
}
/* 修改 */
/**
* 修改数据
* 1. 基本修改数据:setData().forPath()
* 2. 根据版本修改: setData().withVersion().forPath()
* * version 是通过查询出来的。目的就是为了让其他客户端或者线程不
干扰我。
*/
@Test
public void setZnode1() throws Exception {
//修改主要是修改节点存放的数据
Stat stat = client.setData().forPath("/nanfeng2",
"nanzi".getBytes());
//将修改的状态打印查看
System.out.println(stat);
CuratorUtils.clossConnection(client);
}
/* 获取
*/
/**
* 查询节点:
* 1. 查询数据:get: getData().forPath()
* 2. 查询子节点: ls: getChildren().forPath()
* 3. 查询节点状态信息:ls -s:getData().storingStatIn(状态对
象).forPath()
*/
@Test
public void getZnode1() throws Exception {
//查询节点数据
byte[] bytes = client.getData().forPath("/nanfeng2");
System.out.println(Arrays.toString(bytes));
CuratorUtils.clossConnection(client);
}
@Test
public void getZnode2() throws Exception {
//查询子节点
List<String> list = client.getChildren().forPath("/");
System.out.println(list);
CuratorUtils.clossConnection(client);
}
@Test
public void getZnode3() throws Exception {
//查询节点的状态信息
Stat stat = new Stat();
System.out.println(stat);
client.getData().storingStatIn(stat).forPath("/nanfeng1");
//打印刷新后的状态信息
System.out.println(stat);
CuratorUtils.clossConnection(client);
}
}
(3) Watch 事件监听
package test;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.*;
import org.junit.Test;
import utils.CuratorUtils;
import java.util.Arrays;
/**
* @ClassName: WatchTesyt
* @Author: nanfeng
* @Date: 2021/1/20 21:10
* @Description: TODO
*/
public class WatchTest {
CuratorFramework client;
public WatchTest() {
client = CuratorUtils.getClient();
}
@Test
/*1:NodeCache 监听某一个特定的节点*/
public void testNodeCache() throws Exception {
//创建 NodeCache 对象
final NodeCache nodeCache = new NodeCache(client, "/nanfeng1");
//注册监听
nodeCache.getListenable().addListener(new NodeCacheListener()
{
@Override
public void nodeChanged() throws Exception {
//处理节点变化后的业务;
//类似触发器业务
System.out.println("发生改变了");
//获取修改后的数据
byte[] data = nodeCache.getCurrentData().getData();
System.out.println(Arrays.toString(data));
}
});
//开启监听,同时加载缓冲数据
nodeCache.start(true);
//设置死循环为了不断续监听
for (; ; ) {
}
}
/*2:PathChildreCache 监听一个 ZNode 的子节点,不包含本节点*/
public void testPathChildrenCache() throws Exception {
//创建监听器对象
PathChildrenCache pathChildrenCache = new
PathChildrenCache(client,"/nanfeng"/*监听对象*/,true/*缓存状态信息*/);
//绑定监听器
pathChildrenCache.getListenable().addListener(new
PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework curatorFramework,
PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
//发生变化后需要处理的业务代码
//触发某个信息
System.out.println("发生变化了");
//查看这个对象的状态
System.out.println(pathChildrenCacheEvent);
PathChildrenCacheEvent.Type type =
pathChildrenCacheEvent.getType();
//如果 type 是升级,就获取最新的数据
if
(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
//确认是升级了
System.out.println("升级了");
//获取最新的数据
byte[] data =
pathChildrenCacheEvent.getData().getData();
System.out.println(Arrays.toString(data));
}
}
});
//开启监听
pathChildrenCache.start();
//死循环为了查看,当真正部署到服务器不用使用这种
while (true){}
}
/*3:TreeCach 监听整个树的节点 */
public void testTreeCache() throws Exception {
//1. 创建监听器
TreeCache treeCache = new TreeCache(client,"/nanfeng");
//2. 注册监听
treeCache.getListenable().addListener(new TreeCacheListener()
{
@Override
public void childEvent(CuratorFramework client,
TreeCacheEvent event) throws Exception {
System.out.println("节点变化了");
System.out.println(event);
}
});
//3. 开启监听
treeCache.start();
while (true){
}}}
7 分布式锁

相关文章:
zk111111111111111111
Zookeeper 1 zookeeper(作为 dubbo 的注册中心): 概述: zookeper 是 一个分布式的、开源的分布式应用程序的协调服务,管理分布式应 用 作用: 配置管理,分布式锁,集群管理 2 zookeeper 的安装 (dubbo 的资料中已经整理) 3 zookeeper 的数据模型 zookeeper 是一个树形的服…...
018:Mapbox GL加载Google地图(影像瓦片图)
第018个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载google地图。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共80行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xia…...
Web API 和 API 的区别编写api
编写api 自从Roy Fielding博士在2000年他的博士论文中提出(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨重的SOAP,成为Web API的标准了。 什么是Web API呢? 1. Web API 和…...
IDEA 用上这款免费 GPT4 插件,生产力爆表了
大家好,我是一航! 早前给大家分享过GPT的一些玩法,但是依旧有很多铁子没有掌握魔法的奥秘,始终没有用上;前两天,一兄台分享给我一款 IDE 插件:Bito-ChatGPT ,安装就能直接在IDE中使…...
1187.使数组严格递增 学习记录
题目描述 给你两个整数数组 arr1 和 arr2,返回使 arr1 严格递增所需要的最小「操作」数(可能为 0)。 每一步「操作」中,你可以分别从 arr1 和 arr2 中各选出一个索引,分别为 i 和 j,0 < i < arr1.l…...
权限控制_SpringSecurity
认证-授权 认证:系统提供的用于识别用户身份的功能,通常提供用户名和密码进行登录其实就是在进行认证,认证的目的是让系统知道你是谁。 授权:用户认证成功后,需要为用户授权,其实就是指定当前用户可以操作…...
2023年最系统的自动化测试,测试开发面试题,10k以下不建议看
鉴于现在严峻的就业形势,千万大学生即将出新手村,今天给大家打包好了2023最能避免薪资倒挂的《面试圣经》。不经一番寒彻骨,怎得梅花扑鼻香。这份面试题,与君共勉! 一、开场白 Q:简单自我介绍一下吧 Q:项…...
今年SMETA审核费用即将涨价
【今年SMETA审核费用即将涨价】 SMETA全称( Sedex Members Ethical Trade Audit ),即Sedex会员社会道德贸易审核,它是Sedex发起的一种负责任的供应链审计方法/项目。 Sedex是一个全球性的责任商业平台,SMETA是审核方法…...
基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
基于深度学习和生理信号的疾病筛查:个体内和个体间研究的价值与应用
一、引言 随着深度学习技术的飞速发展,基于生理信号的疾病筛查和诊断方法在医学领域得到了广泛应用。这些方法通常利用个体内和个体间的生理信号数据,通过训练深度学习模型实现疾病的自动识别和预测。本文将讨论个体内和个体间研究在这一领域的价值和应…...
现在有t1,t2,t3三个线程,实现t1,t2线程同步执行,然后再执行t3线程,使用Java实现该程序
目录 1、利用CountDownLatch 2、利用Future 最近在面试的时候,经常遇到这个题目,首先从题目上看,就知道考察的是多线程方面知识,我第一次看到这个题目的时候,就想到了使用CountDownLatch这个计数器来实现,…...
83.qt qml-初步学习2D粒子影响器(二)
由于QmlBook in chinese翻译过来的文字有些比较生疏难于理解,所以本章在它的基础上做些个人理解,建议学习的小伙伴最好配合QmlBook in chinese一起学习。 QML粒子所有类型: Qt Quick Particles QML Types | Qt Quick 6.5.0 Affector类型: Attractor QML Type | Qt Quick 6.5.…...
4.17-4.18学习总结
MD5 MD5: 1、压缩性 2、容易计算 3、抗修改性 4、弱抗碰撞 5、强抗碰撞 为什么需要MD5? 存储一些敏感信息的时候,如果不进行加密会出现安全问题。 例如:系统登录的密码,如果数据库中的密码采用明文,一旦数据库泄…...
Spring事务
事务作用: 事务作用:在数据层保障一系列的数据库操作同成功同失败Spring事务作用:在数据层或 业务层 保障一系列的数据库操作同成功同失败 Spring为了管理事务,提供了一个平台事务管理器PlatformTransactionManager commit是用来提…...
Linux新的设备或分区挂载到系统中mount使用方法
如果想将一个新的设备或分区挂载到系统中,可以按照以下步骤进行操作: 确定要挂载的设备或分区的设备名,例如 /dev/sdb1。 创建挂载点,可以在任何目录下创建一个新目录作为挂载点,例如 /mnt/mydevice。 sudo mkdir /mn…...
移动硬盘损坏如何恢复数据
移动硬盘一种小巧便携的存储介质,可用于各电脑之间交换大容量数据,可以随时插拔,进行高速传输数据。但有好也有坏,在我们使用中也会出现一些移动硬盘损坏故障,比如说提示格式化、硬盘分区丢失、误格式化、文件误删除等…...
Material Design:为你的 Android 应用提供精美的 UI 体验
Material Design:为你的 Android 应用提供精美的 UI 体验 介绍 Material Design 概念:介绍 Material Design 是 Google 推出的一种设计语言,用于创建现代、美观、直观且一致的用户界面。解释 Material Design 的基本原则,包括材料…...
springboot+vue学生毕业离校系统(源码+说明文档)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的学生毕业离校系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:风…...
【Android入门到项目实战-- 6.2】—— 如何访问其他应用程序的数据?
目录 一、ContentResolver基本用法 如何查询? 如何向表中添加一条数据? 如何更新这条新添加的数据? 如何删除这条数据? 二、读取系统联系人 要想你的APP访问其他应用程序的数据,需要使用内容提供器,下面使…...
【100个 Unity实用技能】 | InputField输入框组件实现输入限制,只能输入中文或特殊字符等
🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉 🎄 学习专栏推荐:Unity系统学习专栏 🌲 游戏制作专栏推荐:游戏制作 &…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
