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
fi

ZOO_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 表示readonly
    cl.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
    // 创建ZooKeeperAdmin
    zk = 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 printStream
    public void setOut(PrintStream out) {
        this.out = out;
    }

    // Set err printStream
    public void setErr(PrintStream err) {
        this.err = err;
    }

    // set the zookeeper instance
    public void setZk(ZooKeeper zk) {
        this.zk = zk;
    }

    // get the string used to call this command
    public String getCmdStr() {
        return cmdStr;
    }

    // get the option string
    public String getOptionStr() {
        return optionStr;
    }

    // get a usage string, contains the command and the options
    public 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 arguments
    public abstract CliCommand parse(String[] cmdArgs) throws CliParseException;

    // return true if command has watch option, false otherwise
    public 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]");
    }

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

    @Override
    public 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相关命令。

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

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

相关文章

GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程)

&#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程) &#x1f4c1; 文章目录 &#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图…

FLV 封装格式详解

FLV 封装格式详解 FLV 封装格式详解简介FLV 格式FLV headerFLV bodyback-pointerFLV tagFLV tag headerFLV tag data&#xff1a;audio tagFLV tag data&#xff1a;video tagFLV tag data&#xff1a;script tag 总结&#xff1a;FLV 层次结构实例&#xff1a;flvAnalyser 解析…

pytorch演示pipeline并行

pytorch演示pipeline并行 1.单卡内存不够时,可以将网络切分成几段(stage),每个GPU负责一个stage。比如GPU0计算完之后将数据发送给GPU1算后续的stage 2.以上的方式,会导致GPU的利用率不高,可以将输入的batch切分成多份更小的batch,陆续送给GPU0,这样GPU0处理完micro batch0之后…

Anthropic 的 Claude 3 现能从数百个选项中可靠地挑选出合适的工具来完成任务

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

flood_fill 算法|图形渲染

flood fill 算法常常用来找极大连通子图&#xff0c;这是必须掌握的基本算法之一&#xff01; 图形渲染 算法原理 我们可以利用DFS遍历数组把首个数组的值记为color&#xff0c;然后上下左右四个方向遍历二维数组数组如果其他方块的值不等于color 或者越界就剪枝 return 代码…

浮点数在计算机中的存储

这一段代码的输出是什么&#xff1f; int main() {int n 9;float *pFloat (float *)&n;printf("n的值为&#xff1a;%d\n",n);printf("*pFloat的值为&#xff1a;%f\n",*pFloat);*pFloat 9.0;printf("num的值为&#xff1a;%d\n",n);pri…

企业网络安全运营能力的多维度评价及优化策略

网络安全是企业面临的一个日益重要的问题&#xff0c;安全运营能力的强弱直接关系到企业的健康可持续发展和综合竞争力的提升。为推动企业网络安全工作的标准化建设&#xff0c;提升企业的网络安全运营能力&#xff0c;本文从安全建设、安全应对和安全效果三个角度出发&#xf…

如何给MySQL数据库的所有表统一加上字段

在开发过程中&#xff0c;有时候慢慢的建了很多数据库表&#xff0c;但是后来发现需要统一增加某些字段的时候&#xff0c;可以通过alter语句 ALTER TABLE 表名 ADD 列名 数据类型;比如我要给t_user表增加gmt_create与gmt_modified字段&#xff0c;用作记录新增记录时间与更新…

达梦关键字(如:XML,EXCHANGE,DOMAIN,link等)配置忽略

背景&#xff1a;在使用达梦数据库时&#xff0c;查询SQL中涉及XML,EXCHANGE,DOMAIN,link字段&#xff0c;在达梦中是关键字&#xff0c;SQL报关键词不能使用的错误。 解决办法&#xff1a; 配置达梦安装文件E:\MyJava\dmdbms\data\DAMENG\dm.ini 忽略这些关键词&#xff0c;…

CGAL的交叉编译-androidlinux-arm64

由于项目算法需要从Linux移植到android&#xff0c;原先的CGAL库也需要进行移植&#xff0c;先现对CGAL的移植过程做下记录&#xff0c;主要是其交叉编译的过程.。 前提条件&#xff1a; 1、主机已安装NDK编译器&#xff0c;版本大于19 2、主机已安装cmake 和 make 3、主机…

政安晨:【Keras机器学习实践要点】(二十二)—— 基于 TPU 的肺炎分类

目录 简述 介绍 / 布置 加载数据 可视化数据集 建立 CNN 纠正数据失衡 训练模型 拟合模型 可视化模型性能 ​编辑预测和评估结果 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客…

达梦(DM)报错[-3209]: 无效的存储参数

[TOC](达梦(DM)报错[-3209]: 无效的存储参数) 最近有一个项目&#xff0c;一直使用的是达梦数据库&#xff0c;今天遇到了一个问题&#xff0c;就是将测试环境新增加的表导入线上时报错 [-3209]: 无效的存储参数&#xff0c;这里我用我本地的达梦数据库复现一下这个问题&#…

【HTML】简单制作一个动态变色光束花

目录 前言 开始 HTML部分 效果图 ​编辑​编辑​编辑​编辑总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建一个文本文档&#xff0c;其中HTML的文件名改为[index.html]&a…

python-flask后端知识点

anki 简单介绍&#xff1a; 在当今信息爆炸的时代&#xff0c;学习已经不再仅仅是获取知识&#xff0c;更是一项关于有效性和持续性的挑战。幸运的是&#xff0c;我们有幸生活在一个科技日新月异的时代&#xff0c;而ANKI&#xff08;Anki&#xff09;正是一款旗舰级的学习工具…

【深度学习】环境搭建ubuntu22.04

清华官网的conda源 https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ 安装torch conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia 2.2.2 conda install 指引看这里&#xff1a; ref:https://docs.nvidia.com/cuda/cuda-installatio…

高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测

高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测 目录 高创新 | Matlab实现OOA-CNN-GRU-Attention鱼鹰算法优化卷积门控循环单元注意力机制多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现OOA…

css实现各级标题自动编号

本文在博客同步发布&#xff0c;您也可以在这里看到最新的文章 Markdown编辑器大多不会提供分级标题的自动编号功能&#xff0c;但我们可以通过简单的css样式设置实现。 本文介绍了使用css实现各级标题自动编号的方法&#xff0c;本方法同样适用于typora编辑器和wordpress主题…

Qt案例 通过调用Setupapi.h库实现对设备管理器中设备默认驱动的备份

参考腾讯电脑管家-软件市场中的驱动备份专家写的一个驱动备份软件案例&#xff0c;学习Setupapi.h库中的函数使用.通过Setupapi.h库读取设备管理器中安装的设备获取安装的驱动列表&#xff0c;通过bit7z库备份驱动目录下的所有文件. 目录导读 实现效果相关内容示例获取SP_DRVIN…

计算机网络-运输层

运输层 湖科大计算机网络 参考笔记&#xff0c;如有侵权联系删除 概述 运输层的任务&#xff1a;如何为运行在不同主机上的应用进程提供直接的通信服务 运输层协议又称端到端协议 运输层使应用进程看见的好像是在两个运输层实体之间有一条端到端的逻辑通信信道 运输层为应…

Github上传大文件(>25MB)教程

0.在github中创建新的项目&#xff08;已创建可忽略这一步&#xff09; 如上图所示&#xff0c;点击New repository 进入如下页面&#xff1a; 1.下载Git LFS 下载git 2.打开gitbash 3.上传文件&#xff0c;代码如下: cd upload #进入名为upload的文件夹&#xff0c;提前…