勒流网站建设/如何优化网站
Zookeeper概念
Zookeeper是一个树形目录服务,简称zk。
Zookeeper是一个分布式的、开源的分布式应用程序的协调服务
Zookeeper提供主要的功能包括:配置管理,分布式锁,集群管理
Zookeeper命令操作
zk数据模型
zk中的每一个节点都被称为:ZNode,每个节点上都会保存自己的数据和节点信息。节点可以拥有子节点,同时也允许少量(1MB)数据存储在该节点之下
节点可以分为四大类:
- PERSISTENT 持久化节点
- EPHEMERAL 临时节点:-e
- PERSISTENT_SEQUENTIAL持久化顺序节点:-s
- EPHEMERAL_SEQUENTIAL临时顺序节点:-es
zk服务端命令
启动zk服务
./zkServer.sh start
zk查看zk服务状态
./zkServer.sh status
停止zk服务
./zkServer.sh stop
重启zk服务
./zkServer.sh restart
zk客户端命令
zkCli.sh连接ZooKeeper服务命令
./zkCli.sh [-server ip地址:2181] (如果是连接本机zk服务,可以省略[]中的内容)
查看zk中的节点
ls /[节点名称]
创建节点方法
create [节点类型] /父节点 [存储信息] (存储信息可以不写)
临时节点创建 -e(服务器关闭,下次连接就会删除)
顺序节点创建 -s
临时顺序节点创建 -es
查看节点存储信息的方法
get /目录
ls -s 是查询结点状态信息
设置节点数据
set /目录 存储信息
删除节点
delete /目录(只能删除空目录)
deleteall /目录(有子结点也可以删除)
在创建节点时,如果没有指定存储数据,那么默认存储的数据是当前服务器的ip地址
Curator介绍
CUrator是Zookeeper的Java客户端库,常见的Zookeeper Java API有三种:
- 原生Java API
- ZkClient
- Curator
相较于原生Java API,Curator使用较为简单,其次,高版本的Curator可以向下兼容zk,但zk无法向下兼容Curator
Curator API常用操作
连接zk服务
一共有两种连接客户端的方式,一种是通过newClient(),一种是通过Builder链式编程创建客户端对象
@Test
public void test() throws Exception {//指定重试策略RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);//第一种连接zk方式/*参数1:指定需要连接的zk地址与端口,如果是集群模式,使用,分隔开参数2:会话超时时间参数3:连接超时时间参数4:重试策略*/CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.116.131:2181", 60 * 1000, 15 * 1000, retryPolicy);client.start();//第二种连接方式,可以指定namespace,其实是指定根目录(此后该客户端对象的curd操作都会在指定的根目录下进行)CuratorFramework client2 = CuratorFrameworkFactory.builder().connectString("192.168.116.131:2181").sessionTimeoutMs(60 * 1000).connectionTimeoutMs(15 * 1000).retryPolicy(retryPolicy).namespace("zmt").build();client2.start();
}
创建节点
创建节点默认创建节点类型为持久化,返回结果为路径,如果不指定节点存储类型,那么默认存储客户端的ip地址
@Test
public void testCreate() throws Exception {//如果不指定参数2,那么该节点的存储数据为客户端的ip地址String path = client.create().forPath("/app1","zhangsan".getBytes());System.out.println(path);//我们可以通过指定withMode来确定需要创建的节点类型,参数为枚举类client.create().withMode(CreateMode.EPHEMERAL).forPath("/app2");//创建多级节点,创建父结点,如果需要client.create().creatingParentsIfNeeded().forPath("/app3/p1");
}
查询节点
我们可以查询节点的存储信息,也可以查询节点的子节点信息,也可以查询节点的状态信息
@Test
public void testGet() throws Exception {//获取节点存储信息byte[] data = client.getData().forPath("/app1");System.out.println(new String(data));//获取子节点信息List<String> list = client.getChildren().forPath("/app3");System.out.println(list);//获取节点状态信息Stat status = new Stat();client.getData().storingStatIn(status).forPath("/app1");System.out.println(status);
}
修改节点
因为可能存在多个客户端连接同一个zookeeper,因此可能会出现修改节点数据时,其他节点也在修改的问题,因此为了避免出现同时修改同一个数据的情况发生,我们应该先获取数据的版本,然后修改数据时根据数据的版本是否一致再决定是否进行修改。
@Test
public void testSetForVersion() throws Exception {int version;Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app1");version = stat.getVersion();System.out.println(version);client.setData().withVersion(version).forPath("/app1","lisi".getBytes());
}
删除节点
一般我们都要添加guaranteed()方法来避免网络问题产生的删除失败的问题
@Test
public void testDelete() throws Exception {//删除单个节点client.delete().forPath("/app1");//删除多级节点client.delete().deletingChildrenIfNeeded().forPath("/app3");//删除失败进行重试,直到删除成功//比如说网络不好,导致删除失败,可以重复进行删除client.delete().guaranteed().forPath("/app2");//删除回调client.delete().guaranteed().inBackground(new BackgroundCallback() {//执行回调方法@Overridepublic void processResult(CuratorFramework client, CuratorEvent event) throws Exception {System.out.println("节点被删除");System.out.println(event);}}).forPath("/app4");
}
Watch事件监听
zk运行用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,zk服务端会将事件通知到感兴趣的客户端上去,该机制是zk实现分布式协调服务的重要特性。
zk中引入了Watch机制来实现了发布订阅功能,能够让多个订阅者同时监听某一个对象,当一个对象自身状态发生变化时,会通知所有的订阅者
zk提供了3种Watcher:
- NodeCache:只监听一个特定结点
- PathChildrenCache:监控一个Znode的子节点
- TreeCache:前两个结合,监听自己和自己所有子节点
NodeCache的简单使用
@Test
public void testNodeCache() throws Exception {NodeCache nodeCache = new NodeCache(client, "/app1");nodeCache.getListenable().addListener(new NodeCacheListener() {@Overridepublic void nodeChanged() throws Exception {System.out.println("节点发生变化");//获取节点变化后的值byte[] data = nodeCache.getCurrentData().getData();System.out.println(new String(data));}});nodeCache.start();while (true){}
}
PathChildrenCache的简单使用
@Test
public void testChildrenCache() throws Exception {PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/", true);pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {System.out.println("节点发生变化");System.out.println(pathChildrenCacheEvent);PathChildrenCacheEvent.Type type = pathChildrenCacheEvent.getType();if (type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){//如果是update事件byte[] data = pathChildrenCacheEvent.getData().getData();System.out.println(new String(data));}}});pathChildrenCache.start();while (true) {}
}
TreeCache的简单使用
@Test
public void testTreeCache() throws Exception {TreeCache treeCache = new TreeCache(client,"/");treeCache.getListenable().addListener(new TreeCacheListener() {@Overridepublic void childEvent(CuratorFramework curatorFramework, TreeCacheEvent treeCacheEvent) throws Exception {System.out.println("数据发生变化");System.out.println(treeCacheEvent);}});treeCache.start();while (true) {}
}
分布式锁
作用于多个JVM环境,保证多线程安全。
实现分布式锁的原理:当客户端要获取锁时,创建节点,使用完锁,删除该节点
- 客户端获取锁时,在lock节点下创建临时顺序结点
- 然后客户端获取lock下面所有的子节点,如果发现自己创建的子节点序号最小,那么就认为该客户端获取到了锁。使用完后把节点删除
- 如果不是最小的结点,说明此时自己还没有获取到锁,此时客户端需要找到比自己小的哪个结点,同时对其注册事件监听器,监听删除事件。
- 如果比自己小一个的结点被删除,则客户端的Watcher会收到通知,此时再次判断自己的结点是否最小,如果不是,重复以上步骤
采取临时节点是为了避免客户端在获取到锁之后处理业务时宕机,当客户端宕机之后,会话结束,临时节点会自动删除
Curator实现分布式锁API
一共有五种方案:
- 分布式排他锁
- 分布式可重入排他锁
- 分布式读写锁
- 将多个锁作为单个实体管理的容器
- 共享信号量
一个简单的售票案例
public class Ticket12306 implements Runnable {//模拟十张票private int num = 10;//分布式可重入式锁private InterProcessMutex lock;public Ticket12306() {RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 2);CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.116.131:2181").connectionTimeoutMs(60*1000).sessionTimeoutMs(15*1000).retryPolicy(retryPolicy).build();client.start();lock = new InterProcessMutex(client, "/lock");}@Overridepublic void run() {while (true) {try {lock.acquire(3, TimeUnit.SECONDS);if (num > 0) {Thread.sleep(100);System.out.println(Thread.currentThread().getName() + "出售了一张票:" + num);num--;}} catch (Exception e) {System.out.println("我出错了??");e.printStackTrace();} finally {try {lock.release();} catch (Exception e) {e.printStackTrace();}}}}
}
测试
public class TestTicket {@Testpublic void testTicket() throws Exception {Ticket12306 ticket = new Ticket12306();Thread t1 = new Thread(ticket, "携程");Thread t2 = new Thread(ticket, "飞猪");t1.start();t2.start();while(true){}}
}
实现分布式锁的核心代码如下
new 一个锁类型对象lock
lock.acquire()//获取锁
需要上锁的功能
lock.release();//释放锁
相关文章:

Zookeeper的学习笔记
Zookeeper概念 Zookeeper是一个树形目录服务,简称zk。 Zookeeper是一个分布式的、开源的分布式应用程序的协调服务 Zookeeper提供主要的功能包括:配置管理,分布式锁,集群管理 Zookeeper命令操作 zk数据模型 zk中的每一个节点…...

leetcode2两数加和问题(链表)
题目思路: ①创建一个int类型的局部变量,用来存储两个结点的Val值。 ②判断该Val值与10求余(mod)后是否大于0,如果大于0, 则需要在下一个结点进位。 ③最关键的步骤:实现l1,l2结点数值相加后构建新的存储求和后的结点࿰…...

VSCode中配置prettier和ESLint
文章目录 了解ESLint和Prettier的作用prettier配置ESLint配置常见问答ESLint 和Prettier 有什么区别?为什么我应该同时使用ESLint 和Prettier?在使用ESLint 和Prettier 时,有可能出现它们之间的规则冲突吗?我已经在项目中使用了ES…...

如何将本地websocket发布至公网并实现远程访问服务端
文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…...

分享 | 软件测试的基本流程是什么?软件测试流程详细介绍
软件测试 软件测试和软件开发一样,是一个比较复杂的工作过程,如果无章法可循,随意进行测试势必会造成测试工作的混乱。为了使测试工作标准化、规范化,并且快速、高效、高质量地完成测试工作,需要制订完整且具体的测试…...

浮点数的转换--IEEE 754
IEEE754标准是一种浮点数表示标准,一般分为 单精度(32位的二进制数);双精度(64位的二进制数) 根据国际标准IEEE754,任意一个二进制浮点数V可以表示为下面形式: V (-1)^s *&#…...

若依框架介绍
RuoYi(若依)是一款基于Spring Boot、Spring Cloud等开源框架搭建的企业级开发平台,旨在提供全面的解决方案,简化企业级应用开发,提高开发效率。 主要特点: 1. 模块化设计 RuoYi采用模块化的设计࿰…...

iMazing2024免费版iOS移动设备管理软件
以自己的方式管理iPhone,让备受信赖的软件为您传输和保存音乐、消息、文件和数据。安全备份任何 iPhone、iPad 或 iPod touch。iMazing 功能强大、易于使用,称得上是 Mac 和 PC 上最好的 iOS 设备管理器。 正在为iTunes繁琐的操作发愁?设备数…...

Zookeeper整合Java实战,不同客户端使用汇总
Java学习面试指南:https://javaxiaobear.cn ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。可供选择的Java客户端API有: ZooKeeper官方的Java客户端API。 第三方的Java客户端API,比如Curator。 ZooKeeper官方的客户…...

【python】Ubuntu下安装spyder及matplotlib中文显示
一、查看Ubuntu版本 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy尝试用cat /etc/debian_version命令,竟然可以显示出来Debian的版本。 $ cat /etc/debian_version …...

《运维人员的未来:IT界的“万金油“如何继续闪耀光芒》
文章目录 每日一句正能量前言35岁被称为运维半衰期,究竟为何?如何顺利过渡半衰期运维的职业发展路径后记 每日一句正能量 凡事顺其自然,遇事处于泰然,得意之时淡然,失意之时坦然,艰辛曲折必然,历…...

ip addr和ifconfig
ip addr可以显示更多信息,包括为启动的网络驱动如wlan,而ifocnfig只显示在线的驱动。若wlan是down的,则ip addr会显示信息,ifconfig不会显示信息。 ip addr: ifconfig:...

Crow:Middlewares 庖丁解牛7 after_handlers_call_helper
Crow:Middlewares 庖丁解牛6 middleware_call_helper-CSDN博客 介绍了对插件before_handle的调用 当完成了detail::middleware_call_helper的调用后,如果没有在before_handle中设置req被终止处理,也就是 if (!res.completed_) {need_to_call_after_handlers_ = true;handler…...

ts相关笔记(extends、infer、Pick、Omit)
最近刷了本ts小册,对一些知识点做下笔记。 extends extends 是一个关键字,用于对类型参数做一些约束。 A extends B 意味着 A 是 B 的子类型,比如下面是成立的 ‘abc’ extends string599 extends number 看下面例子: type …...

8.21 PowerBI系列之DAX函数专题-帕累托分析
需求 实现 1 按商品小类累积 var rollup_sales calculate(//计算当前累计销售额 [销售额], filter(allselected(order_2[产品小类]),sum(order_2[订单金额])<[销售额]) ) //按小类累积金额,filter内的销售额为选中的各小类的销售额 //金额从大到小累积,用&l…...

结构体-2-测试排名
22-结构体-2-测试排名 [命题人 : 外部导入] 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 为了提升同学们的编程能力,老师们会在平时进行C语言的上机测试,了解班上同学的学习情况,对于一些测试成绩较差的同学,老师会进行督促…...

LeetCode刷题---快乐数
解题思路 该题的解题思路为使用哈希表来存储每次平方的和的结果,看是否有重复的数,如果存在第n次的平方和的数和第i次(i<n)平方和的数想等,那么它就不是一个快乐数。否则,则为快乐数。 代码实现: public boolean i…...

web前端游戏项目-辨色大比拼【附源码】
web前端游戏项目-辨色大比拼【附源码】 《辨色大比拼》是一个旨在测试和提升玩家颜色识别能力的在线游戏。在游戏中,玩家将通过辨识颜色来解谜并推进游戏进程。辨色大比拼也是一个寓教于乐的游戏,它不仅提供了一个有趣的辨色挑战,还能帮助玩…...

MongoDB操作_数据库_集合
.......................................................................................................................................................... 三、MongoDB操作 3.1 数据库操作 一个mongodb中可以建立多个数据库。 MongoDB的默认数据库为"test…...

50个免费的 AI 工具,提升工作效率(附网址)
上次我们已经介绍了20个精选的提高工作效率的免费AI工具,但如果你觉得这些AI工具还不过瘾的话,想进一步成为职场中最了解AI的人,本文将汇总介绍免费最新的50个AI工具。 DeepSwap DeepSwap 是一个基于 AI 的工具,适用于想要制作令人…...

g++ strip debug
strip(1) command_--strip-debug-CSDN博客 strip main.outll main.out -rwxr-xr-x 1 root root 6272 Mar 22 16:14 main.outfile main.out main.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, Bu…...

微服务实战系列之Dubbo(上)
前言 随着一年一度冬至的到来,2023的步伐也将远去。而博主的系列文章,也将从今天起,越来越聚焦如何构建微服务“内核”上。前序系列文章几乎囊括了微服务的方方面面,无论使用什么框架、组件或工具,皆可拿来用之。 那么…...

一篇讲透:箭头函数、普通函数有什么区别
前言 📫 大家好,我是南木元元,热衷分享有趣实用的文章,希望大家多多支持,一起进步! 🍅 个人主页:南木元元 目录 什么是箭头函数 箭头函数和普通函数的区别 更简洁的语法 箭头函数…...

第40节: Vue3 注册生命周期钩子
在UniApp中使用Vue3框架时,你可以注册生命周期钩子来执行特定的逻辑。以下是一个示例,演示了如何在UniApp中使用Vue3框架注册生命周期钩子: <template> <view> <p>{{ message }}</p> </view> </templ…...

docker给容器分配固定ip
1.为 Docker 容器设置一个固定的 IP 地址 要为 Docker 容器设置一个固定的 IP 地址,有几种常见的方法: 使用自定义网络和静态 IP 地址: 你可以创建一个自定义的 Docker 网络,并在这个网络上为容器分配静态 IP 地址。首先&#x…...

Hadoop入门学习笔记——二、在虚拟机里部署HDFS集群
视频课程地址:https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接:https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记(汇总) 目录 二、在虚拟机里部署HDFS集群2.1. 部署node1虚拟机2.2. 部…...

Spring之国际化:i18n
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…...

Java读取类路径下的JSON文件并转换为实体列表
使用 Jackson 库来读取类路径下的 JSON 文件并将其转换为对应实体列表。 在实际开发中可能在本地环境中需要调用别人的接口,别人的接口如果还没开发好或者本地环境不支持外部接口调用的时候,可以读取json文件来造数据,方便调试。 以Student…...
复分析——第1章——复分析准备知识(E.M. Stein R. Shakarchi)
第一章 复分析准备知识 (Preliminaries to Complex Analysis) The sweeping development of mathematics during the last two centuries is due in large part to the introduction of complex numbers; paradoxically, this is based on the seemingly absurd no…...