zookeeper源码(12)命令行客户端
zkCli.sh脚本
这个命令行脚本在bin目录下:
ZOOBIN="${BASH_SOURCE-$0}"
ZOOBIN="$(dirname "${ZOOBIN}")"
ZOOBINDIR="$(cd "${ZOOBIN}"; pwd)"# 加载zkEnv.sh脚本
if [ -e "$ZOOBIN/../libexec/zkEnv.sh" ]; then. "$ZOOBINDIR"/../libexec/zkEnv.sh
else. "$ZOOBINDIR"/zkEnv.sh
fiZOO_LOG_FILE=zookeeper-$USER-cli-$HOSTNAME.log"$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.log.file=${ZOO_LOG_FILE}" \-cp "$CLASSPATH" $CLIENT_JVMFLAGS $JVMFLAGS \org.apache.zookeeper.ZooKeeperMain "$@"
可以看到使用org.apache.zookeeper.ZooKeeperMain作为主类。
ZooKeeperMain入口类
The command line client to ZooKeeper.
idea运行
main方法入口
public static void main(String[] args) throws IOException, InterruptedException {ZooKeeperMain main = new ZooKeeperMain(args);// 执行命令main.run();
}public ZooKeeperMain(String[] args) throws IOException, InterruptedException {// 用于解析命令行选项// -server host1:port1,host2:port2 -timeout 30000 -r// -r 表示readonlycl.parseOptions(args);System.out.println("Connecting to " + cl.getOption("server"));// 连接zookeeper服务器connectToZK(cl.getOption("server"));
}
连接服务器
protected void connectToZK(String newHost) throws InterruptedException, IOException {// 略host = newHost;boolean readOnly = cl.getOption("readonly") != null;if (cl.getOption("secure") != null) {System.setProperty(ZKClientConfig.SECURE_CLIENT, "true");System.out.println("Secure connection is enabled");}ZKClientConfig clientConfig = null;if (cl.getOption("client-configuration") != null) {try {clientConfig = new ZKClientConfig(cl.getOption("client-configuration"));} catch (QuorumPeerConfig.ConfigException e) {e.printStackTrace();ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue());}}if (cl.getOption("waitforconnection") != null) {connectLatch = new CountDownLatch(1);}int timeout = Integer.parseInt(cl.getOption("timeout")); // 默认30000// 创建ZooKeeperAdminzk = new ZooKeeperAdmin(host, timeout, new MyWatcher(), readOnly, clientConfig);// 等待连接完成if (connectLatch != null) {if (!connectLatch.await(timeout, TimeUnit.MILLISECONDS)) {zk.close();throw new IOException(KeeperException.create(KeeperException.Code.CONNECTIONLOSS));}}
}
执行命令
void run() throws IOException, InterruptedException {if (cl.getCommand() == null) {System.out.println("Welcome to ZooKeeper!");boolean jlinemissing = false;// only use jline if it's in the classpath// jline命令行工具 略if (jlinemissing) { // 当jline工具不可用时,使用原生标准输入接收客户端命令System.out.println("JLine support is disabled");BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line;while ((line = br.readLine()) != null) {executeLine(line); // 解析命令之后调用processCmd方法}}} else {// Command line args non-null. Run what was passed.processCmd(cl);}
}protected boolean processCmd(MyCommandOptions co) throws IOException, InterruptedException {boolean watch = false;try {watch = processZKCmd(co);exitCode = ExitCode.EXECUTION_FINISHED.getValue();} catch (CliException ex) {exitCode = ex.getExitCode();System.err.println(ex.getMessage());}return watch;
}protected boolean processZKCmd(MyCommandOptions co) throws CliException, IOException, InterruptedException {String[] args = co.getArgArray();String cmd = co.getCommand();// 略boolean watch = false;// quit、redo、history、connect等命令// 获取命令处理类CliCommand cliCmd = commandMapCli.get(cmd);if (cliCmd != null) {cliCmd.setZk(zk);watch = cliCmd.parse(args).exec();} else if (!commandMap.containsKey(cmd)) {usage(); // 打印帮助}return watch;
}
CliCommand抽象类
Base class for all CLI commands.
public abstract class CliCommand {protected ZooKeeper zk;protected PrintStream out;protected PrintStream err;private String cmdStr;private String optionStr;public CliCommand(String cmdStr, String optionStr) {this.out = System.out;this.err = System.err;this.cmdStr = cmdStr;this.optionStr = optionStr;}// Set out printStreampublic void setOut(PrintStream out) {this.out = out;}// Set err printStreampublic void setErr(PrintStream err) {this.err = err;}// set the zookeeper instancepublic void setZk(ZooKeeper zk) {this.zk = zk;}// get the string used to call this commandpublic String getCmdStr() {return cmdStr;}// get the option stringpublic String getOptionStr() {return optionStr;}// get a usage string, contains the command and the optionspublic String getUsageStr() {return cmdStr + " " + optionStr;}// add this command to a map. Use the command string as key.public void addToMap(Map<String, CliCommand> cmdMap) {cmdMap.put(cmdStr, this);}// parse the command argumentspublic abstract CliCommand parse(String[] cmdArgs) throws CliParseException;// return true if command has watch option, false otherwisepublic abstract boolean exec() throws CliException;
}
CreateCommand示例
以CreateCommand为例说明一下CliCommand的使用方式:
public class CreateCommand extends CliCommand {private static Options options = new Options();private String[] args;private CommandLine cl;static {options.addOption(new Option("e", false, "ephemeral"));options.addOption(new Option("s", false, "sequential"));options.addOption(new Option("c", false, "container"));options.addOption(new Option("t", true, "ttl"));}public CreateCommand() {super("create", "[-s] [-e] [-c] [-t ttl] path [data] [acl]");}@Overridepublic CliCommand parse(String[] cmdArgs) throws CliParseException {DefaultParser parser = new DefaultParser();try {cl = parser.parse(options, cmdArgs);} catch (ParseException ex) {throw new CliParseException(ex);}args = cl.getArgs();if (args.length < 2) {throw new CliParseException(getUsageStr());}return this;}@Overridepublic boolean exec() throws CliException {boolean hasE = cl.hasOption("e");boolean hasS = cl.hasOption("s");boolean hasC = cl.hasOption("c");boolean hasT = cl.hasOption("t");if (hasC && (hasE || hasS)) {throw new MalformedCommandException("-c cannot be combined with -s or -e. Containers cannot be ephemeral or sequential.");}long ttl;try {ttl = hasT ? Long.parseLong(cl.getOptionValue("t")) : 0;} catch (NumberFormatException e) {throw new MalformedCommandException("-t argument must be a long value");}if (hasT && hasE) {throw new MalformedCommandException("TTLs cannot be used with Ephemeral znodes");}if (hasT && hasC) {throw new MalformedCommandException("TTLs cannot be used with Container znodes");}CreateMode flags;if (hasE && hasS) {flags = CreateMode.EPHEMERAL_SEQUENTIAL;} else if (hasE) {flags = CreateMode.EPHEMERAL;} else if (hasS) {flags = hasT ? CreateMode.PERSISTENT_SEQUENTIAL_WITH_TTL : CreateMode.PERSISTENT_SEQUENTIAL;} else if (hasC) {flags = CreateMode.CONTAINER;} else {flags = hasT ? CreateMode.PERSISTENT_WITH_TTL : CreateMode.PERSISTENT;}if (hasT) {try {EphemeralType.TTL.toEphemeralOwner(ttl);} catch (IllegalArgumentException e) {throw new MalformedCommandException(e.getMessage());}}String path = args[1];byte[] data = null;if (args.length > 2) {data = args[2].getBytes(UTF_8);}List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;if (args.length > 3) {acl = AclParser.parse(args[3]);}try {// 调用zookeeper客户端创建节点String newPath = hasT? zk.create(path, data, acl, flags, new Stat(), ttl): zk.create(path, data, acl, flags);// 打印返回值err.println("Created " + newPath);} catch (IllegalArgumentException ex) {throw new MalformedPathException(ex.getMessage());} catch (KeeperException.EphemeralOnLocalSessionException e) {err.println("Unable to create ephemeral node on a local session");throw new CliWrapperException(e);} catch (KeeperException.InvalidACLException ex) {err.println(ex.getMessage());throw new CliWrapperException(ex);} catch (KeeperException | InterruptedException ex) {throw new CliWrapperException(ex);}return true;}
}
ZooKeeperAdmin类
This is the main class for ZooKeeperAdmin client library. This library is used to perform cluster administration tasks, such as reconfigure cluster membership. The ZooKeeperAdmin class inherits ZooKeeper and has similar usage pattern as ZooKeeper class. Please check ZooKeeper class document for more details.
继承了ZooKeeper类,扩展了reconfig相关命令。
相关文章:

zookeeper源码(12)命令行客户端
zkCli.sh脚本 这个命令行脚本在bin目录下: ZOOBIN"${BASH_SOURCE-$0}" ZOOBIN"$(dirname "${ZOOBIN}")" ZOOBINDIR"$(cd "${ZOOBIN}"; pwd)"# 加载zkEnv.sh脚本 if [ -e "$ZOOBIN/../libexec/zkEnv.sh&qu…...

深度学习的数学基础--Homework2
学习资料:https://www.bilibili.com/video/BV1mg4y187qv/?spm_id_from333.788.recommend_more_video.1&vd_sourced6b1de7f052664abab680fc242ef9bc1 神经网络的特点:它不是一个解析模型,它的储存在一堆参数里面(确定一个超平…...

什么是HW,企业如何进行HW保障?
文章目录 一、什么是HW二、HW行动具体采取了哪些攻防演练措施三、攻击方一般的攻击流程和方法四、企业HW保障方案1.建意识2.摸家底3.固城池4.配神器5.增值守 一、什么是HW 网络安全形势近年出现新变化,网络安全态势变得越来越复杂,黑客攻击入侵、勒索病…...

【Redis系列】Spring Boot 集成 Redis 实现缓存功能
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Flutter之Flex组件布局
目录 Flex属性值 轴向:direction:Axis.horizontal 主轴方向:mainAxisAlignment:MainAxisAlignment.center 交叉轴方向:crossAxisAlignment:CrossAxisAlignment 主轴尺寸:mainAxisSize 文字方向:textDirection:TextDirection 竖直方向排序:verticalDirection:VerticalDir…...

【Linux】TCP编程{socket/listen/accept/telnet/connect/send}
文章目录 1.TCP接口1.1socket文档 1.2listen拓:端口号8080 1.3accept拓:今天全局函数 1.4读写接口1.5telnet1.一个客户端2.两个客户端 1.6ulimit -a1.7常识回顾1.8connect1.9拓:客户端的ip和地址什么时候被分配?1.10拓:…...
【WPF应用33】WPF基本控件-TabControl的详解与示例
在Windows Presentation Foundation(WPF)中,TabControl控件是一个强大的界面元素,它允许用户在多个标签页之间切换,每个标签页都可以显示不同的内容。这种控件在组织信息、提供选项卡式界面等方面非常有用。在本篇博客…...

[C语言]——动态内存管理
目录 一.为什么要有动态内存分配 二.malloc和free 1.malloc 2.free 三.calloc和realloc 1.calloc 2.realloc 3.空间的释放编辑 四.常见的动态内存的错误 1.对NULL指针的解引用操作 2.对动态开辟空间的越界访问 3.对非动态开辟内存使用free释放 4.使用free释放⼀块…...

C++ 学习笔记
文章目录 【 字符串相关 】C 输入输出流strcpy_s() 字符串复制输出乱码 【 STL 】各个 STL 支持的常见方法 ? : 运算符switch case 运算符 switch(expression) {case constant-expression :statement(s);break; // 可选的case constant-expression :statement(s);break; //…...
本科生学深度学习一残差网络,解决梯度消失和爆炸
看到订阅的激励还在继续,今天写下残差网络 1、梯度爆炸和梯度消失 梯度爆炸和梯度消失是两种常见的问题,由神经网络的结构和参数初始化方式引起。它们都与深度神经网络中的反向传播过程相关。 梯度爆炸:这是指在反向传播期间,梯度逐渐增大并最终超出了有效范围。这通常发…...

初识SpringMVC
一、什么是MVC MVC是一种软件架构模式(是一种软件架构设计思想,不止Java开发中用到,其它语言也需要用到),它将应用分为三块: M:Model(模型)V:View(…...

【Leetcode】2009. 使数组连续的最少操作数
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 给你一个整数数组 n u m s nums nums 。每一次操作中,你可以将 n u m s nums nums 中 任意 一个元素替换成 任意 整数。 如果 n u m s nums nums 满足以下条件&…...

LeetCode-347. 前 K 个高频元素【数组 哈希表 分治 桶排序 计数 快速选择 排序 堆(优先队列)】
LeetCode-347. 前 K 个高频元素【数组 哈希表 分治 桶排序 计数 快速选择 排序 堆(优先队列)】 题目描述:解题思路一:哈希表记录出现次数,然后用最小堆取,因为每次都是弹出最小的,剩下的一定是K…...
K8S Deployment HA
文章目录 K8S Deployment HA1.机器规划2.前期准备2.1 安装ansible2.2 修改 hostname2.3 配置免密2.4 时间同步2.5 系统参数调整2.6 安装 Docker2.7 部署 HaproxyKeepalived 3. 部署 K8S3.1 安装 k8s命令3.2 k8s初始化3.3 添加其他master节点3.4 添加 Node节点3.5 安装 CNI3.6 查…...
【Linux】linux 在指定根目录下,查找wav文件并删除
要在Linux的指定根目录下查找.wav文件并删除它们,您可以使用find命令结合-exec选项来执行删除操作。请注意,这个操作是不可逆的,所以在执行之前请确保您知道自己在做什么,并且已经备份了重要数据。 以下是一个示例命令࿰…...

三、SpringBoot3 整合 SpringMVC
本章概要 实现过程web 相关配置静态资源处理自定义拦截器(SpringMVC 配置) 3.1 实现过程 创建程序引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www…...

设计模式之解释器模式(上)
解释器模式 1)概述 1.定义 定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。 2.结构图 3.角色 AbstractExpression(抽象表达式):在抽象表达…...
[23年蓝桥杯] 买二赠一
题目描述 【问题描述】 某商场有 N 件商品,其中第 i 件的价格是 A i 。现在该商场正在进行 “ 买二 赠一” 的优惠活动,具体规则是: 每购买 2 件商品,假设其中较便宜的价格是 P (如果两件商品价格一样, 则…...
PgSQL的with as语法
returning 返回的这一些字段,然后进行汇总为remove_alarms 然后select一下remove_alarms 出来的数据然后保存到tb_alarm_his 里面 with remove_alarms as( delete fromtb_alarm whereid in (508) returning 0,now(),admin,alarmadvice,alarmadvicecn,alarmarises…...
六、c++代码中的安全风险-fopen
(misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). 为…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...

Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...

claude3.7高阶玩法,生成系统架构图,国内直接使用
文章目录 零、前言一、操作指南操作指导 二、提示词模板三、实战图书管理系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 在线考试系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 四、感受 零、前言 现在很多AI大模型可以…...