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). 为…...
并行总线信号长度匹配与偏斜优化—DDR/总线类设计避坑指南
并行总线(如DDR内存总线、地址数据总线、FPGA并行IO总线)是嵌入式、工控、服务器产品的核心信号链路,总线包含数十路同步信号,长度匹配不当、组间偏斜超标,会直接导致内存读写错误、系统蓝屏、数据丢包,而且…...
OBS录屏零基础入门:5分钟搞定显示器/窗口捕获(含常见问题解决)
OBS录屏零基础入门:5分钟搞定显示器/窗口捕获(含常见问题解决) 第一次打开OBS时,那个黑漆漆的界面是不是让你有点懵?别担心,这就像第一次拿到单反相机时的感觉——看似复杂,实则简单。作为一款开…...
Sanger测序 vs NGS vs 三代测序:如何选择最适合你的实验需求(含详细对比表)
Sanger测序 vs NGS vs 三代测序:如何选择最适合你的实验需求 在基因组学研究的工具箱里,测序技术就像不同倍数的显微镜——每种技术都有其独特的"焦距"和"分辨率"。当实验室新购置了一台Oxford Nanopore设备时,我们团队曾…...
Excel数据透视表实战:5分钟搞定销售数据分析(附常见错误排查)
Excel数据透视表实战:5分钟搞定销售数据分析(附常见错误排查) 当你面对密密麻麻的销售数据表格时,是否曾感到无从下手?数据透视表就是Excel中最强大的"数据翻译官",它能将杂乱无章的销售记录瞬间…...
PreMo库:Arduino差速机器人纯追踪虚拟路径跟随实现
1. PreMo-Virtual Path Following 库技术解析:面向差速驱动机器人的纯追踪虚拟路径跟随实现1.1 库定位与工程价值PreMo(PreciseMovement)库是专为Arduino平台设计的嵌入式运动控制中间件,其核心目标并非替代底层电机驱动或PID闭环…...
保姆级教程:用MATLAB 2022b和STM32G431RB搞定无感FOC,从电机参数识别到代码生成
从零构建无感FOC系统:MATLAB与STM32G431RB的深度实践指南 引言:为什么选择无感FOC技术? 在电机控制领域,磁场定向控制(FOC)因其高效率、低噪音和精准控制特性,已成为工业界和学术界的黄金标准。而无需位置传感器的无感…...
JAVA-Mybaits
1. Mybaits简介 1.1 mybaits是什么 mybaits 是一个半 ORM (对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建 statement等繁杂的过程。程序员直接编…...
DeerFlow实战效果:一键生成播客内容的神奇体验
DeerFlow实战效果:一键生成播客内容的神奇体验 1. DeerFlow播客生成功能初体验 1.1 从零开始创建第一个播客 第一次使用DeerFlow生成播客的经历让我印象深刻。在Web界面简单输入"生成一期关于人工智能在医疗领域应用的15分钟播客"后,系统在…...
铁路关键部件缺陷检测数据集全览(涵盖吊弦病害、绝缘子缺陷、螺栓松动与轨道裂缝)
1. 铁路关键部件缺陷检测数据集概述 铁路作为国家重要的交通基础设施,其安全运行直接关系到乘客生命财产安全。近年来,随着计算机视觉技术的快速发展,基于深度学习的铁路关键部件缺陷检测方法逐渐成为研究热点。而要训练出高精度的检测模型&a…...
Redis排行榜实战:从崩溃到毫秒级响应
从一个崩溃的排行榜说起 你是一个游戏服务器开发。 游戏上线第一天,策划跑过来说:“我们要一个战力排行榜。实时的。玩家打开排行榜,能看到全服前100名。还能看到自己排第几。” 你想了想,觉得不难。数据库里有每个玩家的战力值。…...
